Compare commits

...

60 Commits

Author SHA1 Message Date
Heimen Stoffels 26a5c77ac9 Translated using Weblate (Dutch)
Currently translated at 100.0% (114 of 114 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/nl/
3 months ago
TDE Weblate 24128f051f Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/
3 months ago
TDE Gitea add017f8d7 Update translation template. 3 months ago
mio d9afd6ce2b Add mute checkbox to volume slider
Part of https://mirror.git.trinitydesktop.org/gitea/TDE/codeine/issues/5
Signed-off-by: mio <stigma@disroot.org>
3 months ago
Toad114514 6a71a1b414 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (113 of 113 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/zh_Hans/
4 months ago
TDE Weblate 37df0c3b3c Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/
4 months ago
Heimen Stoffels c95752783f Translated using Weblate (Dutch)
Currently translated at 100.0% (113 of 113 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/nl/
4 months ago
Heimen Stoffels 1dfa2eceb8 Added translation using Weblate (Dutch) 4 months ago
Temuri Doghonadze f42a5e6b63 Translated using Weblate (Georgian)
Currently translated at 100.0% (113 of 113 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/ka/
4 months ago
TDE Weblate 9795d15ce0 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/
5 months ago
TDE Gitea 88ec977bd3 Update translation template. 5 months ago
mio 430d1bae9d Add context menu to audioView
Allows people to toggle the analyzer visibility.

Signed-off-by: mio <stigma@disroot.org>
5 months ago
mio 5e57ab35af Add context menu to status bar
It adds an item which toggles the visibility of the Analyzer when
watching videos.

Signed-off-by: mio <stigma@disroot.org>
5 months ago
Toad114514 adb9e2e081 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (112 of 112 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/zh_Hans/
6 months ago
Toad114514 f69f7a9c90 Translated using Weblate (Chinese (Simplified))
Currently translated at 97.3% (109 of 112 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/zh_Hans/
6 months ago
Michele Calgaro a130452020
Use tdeApp
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
6 months ago
Toad114514 fc0e591805 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (5 of 5 strings)

Translation: applications/codeine - desktop files
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine-desktop-files/zh_Hans/
6 months ago
Toad114514 59fb0ad08a Translated using Weblate (Chinese (Simplified))
Currently translated at 96.4% (108 of 112 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/zh_Hans/
6 months ago
Toad114514 9e176a25db Added translation using Weblate (Chinese (Simplified)) 6 months ago
TDE Weblate 0703015aed Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/
7 months ago
Juan M Ayala 2b775a1e86 Translated using Weblate (Spanish)
Currently translated at 100.0% (5 of 5 strings)

Translation: applications/codeine - desktop files
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine-desktop-files/es/
7 months ago
TDE Gitea d576f98f1d Update translation template. 7 months ago
mio 5cfecec409 Create a AudioView widget for audio-only streams
Currently Codeine will show a blank area when playing an audio-only
file, such as music.  This patch adds a new widget that contains an
instance of the Analyzer::Block class, so instead of a blank area it
contains a "visualizer" of sorts.

Signed-off-by: mio <stigma@disroot.org>
7 months ago
Temuri Doghonadze e023e2eafb Translated using Weblate (Georgian)
Currently translated at 100.0% (112 of 112 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/ka/
7 months ago
TDE Weblate 684ee3e282 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/
8 months ago
TDE Gitea 711611feb3 Update translation template. 8 months ago
mio 14b52b5a46 Fix mouse events not changing volume
Using the scroll wheel over the volume slider would not change the
volume, neither would dragging the slider (until released) or clicking
on the slider.

This patch fixes the above.

See: TDE/codeine#5
Signed-off-by: mio <stigma@disroot.org>
8 months ago
Temuri Doghonadze cdea6d11c3 Translated using Weblate (Georgian)
Currently translated at 100.0% (112 of 112 strings)

Translation: applications/codeine
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine/ka/
9 months ago
Temuri Doghonadze 488e5c81fe Added translation using Weblate (Georgian) 9 months ago
TDE Gitea 4eacc38917 Update translation template. 9 months ago
mio 462472610d Allow seeking in FLAC
Xine has supported seeking in FLAC files since 1.1.16.

Signed-off-by: mio <stigma@disroot.org>
9 months ago
Temuri Doghonadze 32704bb7fa Translated using Weblate (Georgian)
Currently translated at 100.0% (5 of 5 strings)

Translation: applications/codeine - desktop files
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine-desktop-files/ka/
9 months ago
Temuri Doghonadze e1bc4ff086 Added translation using Weblate (Georgian) 9 months ago
TDE Gitea 1ca971bd72 Update translation template. 9 months ago
mio ff2a5768dd Update the xineScope to remove global variables.
This patch updates xineScope.c to better align with Amarok's code. As a
result, the analyzer is more accurate.  For instance, when playing an
audio file and there is a silent spot, the blocks will correctly "drop"
to the bottom, leaving an empty analyzer.  The previous behaviour would
leave some blocks "stuck" in their position

See: TDE/codeine#23
Signed-off-by: mio <stigma@disroot.org>
9 months ago
mio a3ea0ee70f Fix the audio analyzer
Most of the code was already borrowed from Amarok, but wasn't properly
finished. This just updates the code to more closely match what is
currently in TDE's Amarok.

The Analyzer still sits in the statusBar(), which is cool, but can have
some delays when watching a video (the video itself is unaffected).

See: TDE/codeine#23
Signed-off-by: mio <stigma@disroot.org>
10 months ago
TDE Gitea 6eb38b0280 Update translation template. 10 months ago
mio f460840a5e Fix channel selection menus disappearing
When adding/removing an action to/from the toolbar, the aspect ratio,
audio channel, and subtitle channel menus would disappear from the
parent settings menu.

My understanding is that this happened because nothing was keeping those
menus present (plugged?) when other actions were plugged/unplugged.

This changes it so "Aspect Ratio", "Subtitles", and "Audio Channels"
each are a TDESelectAction that is dynamically filled with items. This
way, each popup menu is still present after other actions being
plugged/unplugged.

Resolves: TDE/codeine#24
Signed-off-by: mio <stigma@disroot.org>
10 months ago
TDE Gitea cc8974895a Update translation template. 10 months ago
mio 9ef39acd5d Address -Wall warnings
VideoWindow::ExposeEvent wasn't being used correctly; it should be a
TQCustomEvent (although, the 3000 type is already being used for
forwarding XINE_PROGRESS_EVENT).

While the pts_per_smpls part never seemed to be encountered, it would
have resulted in a floating point exception as it's always 0.  Commented
out to leave a hint as to what the code should be doing.

Resolves: TDE/codeine#2
Signed-off-by: mio <stigma@disroot.org>
10 months ago
mio c0311bdfc3 Fix filter list when opening a file
Signed-off-by: mio <stigma@disroot.org>
11 months ago
TDE Gitea f6d6e20609 Update translation template. 11 months ago
mio 11c0638baf Improve the layout of XineConfigDialog
Properly display the description of each of the settings.  Also,
reorganize the layout so that it uses layouts rather than VBox/HBox.

The TabWidget class has been removed in favour of the standard
TQTabWidget class, as the different behaviour doesn't make a notable
visual difference.

Signed-off-by: mio <stigma@disroot.org>
11 months ago
mio b62e6bc2b9 Fix crash when showing context menu in DVDs
Signed-off-by: mio <stigma@disroot.org>
11 months ago
TDE Gitea 36a0b3510b Update translation template. 12 months ago
mio ed55bf0726 Use nullptr instead of NULL/0 pointer in C++ files
See: https://mirror.git.trinitydesktop.org/gitea/TDE/tde/issues/73
Signed-off-by: mio <stigma@disroot.org>
12 months ago
mio 5e965846d1 Use safer xine_get_current_frame_s
xine_get_current_frame was deprecated back in 2019 because it is
"unsafe by design"[0].  The '_s' version was introduced in xine-lib
1.1.11, which was released in 2008, so there are no version checks.

[0]:
c1a154c1a8/

Signed-off-by: mio <stigma@disroot.org>
12 months ago
TDE Gitea 54d1a665f8 Update translation template. 12 months ago
mio 000a65ca62 Scale capture preview if it exceeds screen bounds
Signed-off-by: mio <stigma@disroot.org>
12 months ago
Michele Calgaro 173770f0f1
Rename __KDE_HAVE_GCC_VISIBILITY to __TDE_HAVE_GCC_VISIBILITY
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
1 year ago
Michele Calgaro e097d43a06
Use centralized cmake version
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
1 year ago
Michele Calgaro 00a73f1dea
Replace Qt with TQt
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
1 year ago
Michele Calgaro 1ca6231ff7
Use new TQ_METHOD, TQ_SIGNAL, TQ_SLOT defines
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
2 years ago
Slávek Banko 6208d03e3d
Raise the minimum required version of CMake to 3.5.
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
2 years ago
TDE Gitea 033f32ab43 Update translation template. 2 years ago
Michele Calgaro b5977d5e67
xine engine: make volume control logarithmic for versions of xine < 1.2.13. For xine versions >= 1.2.13, libxine already makes the volume logarithmic. This relates to TDE/tdemultimedia#40.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
2 years ago
TDE Gitea 28a3b75fba Update translation template. 2 years ago
Michele Calgaro 1884d0e5a2
Fix volume slider functionality and visualization
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
2 years ago
TDE Weblate 9f39f05e56 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: applications/codeine - desktop files
Translate-URL: https://mirror.git.trinitydesktop.org/weblate/projects/applications/codeine-desktop-files/
2 years ago
Michele Calgaro ea718087e4
Replace Q_OBJECT with TQ_OBJECT
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
2 years ago

@ -9,7 +9,11 @@
# #
################################################# #################################################
cmake_minimum_required( VERSION 3.1 )
##### set project version ########################
include( TDEVersion )
cmake_minimum_required( VERSION ${TDE_CMAKE_MINIMUM_VERSION} )
##### include our cmake modules ################# ##### include our cmake modules #################

@ -7,7 +7,11 @@
############################################ ############################################
cmake_minimum_required( VERSION 3.1 ) ##### set project version ########################
include( TDEVersion )
cmake_minimum_required( VERSION ${TDE_CMAKE_MINIMUM_VERSION} )
tde_set_project_version( )
#### general package setup #### general package setup
@ -31,11 +35,6 @@ include( CheckCXXSourceCompiles )
include( TDEMacros ) include( TDEMacros )
##### set version number ########################
tde_set_project_version( )
##### setup install paths ##### setup install paths
include( TDESetupPaths ) include( TDESetupPaths )

@ -8,7 +8,7 @@
Playback finished message (amaroK statusbar code?) Playback finished message (amaroK statusbar code?)
Mouse move to show toolbar in fullscreen mode Mouse move to show toolbar in fullscreen mode
People are likely to use "F" keyboard shortcut or escape after film ends in fullscreen mode People are likely to use "F" keyboard shortcut or escape after film ends in fullscreen mode
but the popup of the menu prevents this, as for some reason Qt stops handling keyboard but the popup of the menu prevents this, as for some reason TQt stops handling keyboard
shortcuts. We need a solution. The escape issue makes the popup menu less useful. So shortcuts. We need a solution. The escape issue makes the popup menu less useful. So
escape with the menu should exit fullscreen too. All shortcuts in the menu should work. escape with the menu should exit fullscreen too. All shortcuts in the menu should work.
Shortcuts not in the menu shouldn't work as this is a modal menu! Could be dangerous. Shortcuts not in the menu shouldn't work as this is a modal menu! Could be dangerous.

@ -1,7 +1,7 @@
#define VERSION "@VERSION@" #define VERSION "@VERSION@"
// Defined if you have fvisibility and fvisibility-inlines-hidden support. // Defined if you have fvisibility and fvisibility-inlines-hidden support.
#cmakedefine __KDE_HAVE_GCC_VISIBILITY 1 #cmakedefine __TDE_HAVE_GCC_VISIBILITY 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */ significant byte first (like Motorola and SPARC, unlike Intel). */

@ -348,7 +348,7 @@ distribution. -->
<title>Credits and License</title> <title>Credits and License</title>
<sect1 id="kapp"> <sect1 id="tdeApp">
<title>&codeine;</title> <title>&codeine;</title>
<para>Program copyright 2004 Max B. Howell <email>max.howell@methylblue.com</email></para> <para>Program copyright 2004 Max B. Howell <email>max.howell@methylblue.com</email></para>

@ -49,7 +49,7 @@ application-specific options.
\*(T<\fB\-\-help\fR\*(T> \*(T<\fB\-\-help\fR\*(T>
Show help about options Show help about options
.TP .TP
\*(T<\fB\-\-help\-qt\fR\*(T> \*(T<\fB\-\-help\-tqt\fR\*(T>
Show TQt specific options Show TQt specific options
.TP .TP
\*(T<\fB\-\-help\-tde\fR\*(T> \*(T<\fB\-\-help\-tde\fR\*(T>

@ -1,5 +1,5 @@
<!DOCTYPE kpartgui> <!DOCTYPE kpartgui>
<kpartgui name="codeine" version="4"> <kpartgui name="codeine" version="5">
<MenuBar> <MenuBar>
<Menu name="file" noMerge="1"><text>&amp;Play</text> <Menu name="file" noMerge="1"><text>&amp;Play</text>
<Action name="play_media"/> <Action name="play_media"/>
@ -10,9 +10,12 @@
<Action name="file_quit"/> <Action name="file_quit"/>
</Menu> </Menu>
<Menu name="settings" noMerge="1"><text>&amp;Settings</text> <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
<Separator/><!-- this seperator doesn't show :( --> <Action name="aspect_ratio_select"/>
<Action name="audio_channels_select"/>
<Action name="subtitle_channels_select"/>
<Separator/>
<Action name="fullscreen"/> <Action name="fullscreen"/>
<Separator/><!-- this seperator doesn't show :( --> <Separator/>
<Action name="options_configure_keybinding"/> <Action name="options_configure_keybinding"/>
<Action name="options_configure_toolbars"/> <Action name="options_configure_toolbars"/>
<Separator/> <Separator/>

@ -35,6 +35,7 @@ tde_add_executable( ${PROJECT_NAME} AUTOMOC
playDialog.cpp playDialog.cpp
listView.cpp listView.cpp
adjustSizeButton.cpp adjustSizeButton.cpp
audioView.cpp
fullScreenAction.cpp fullScreenAction.cpp
insertAspectRatioMenuItems.cpp insertAspectRatioMenuItems.cpp
playlistFile.cpp playlistFile.cpp

@ -29,12 +29,12 @@ namespace Codeine
setFrameStyle( TQFrame::Plain | TQFrame::Box ); setFrameStyle( TQFrame::Plain | TQFrame::Box );
m_preferred = new KPushButton( KGuiItem( i18n("Preferred Scale"), "viewmag" ), this ); m_preferred = new KPushButton( KGuiItem( i18n("Preferred Scale"), "viewmag" ), this );
connect( m_preferred, SIGNAL(clicked()), tqApp->mainWidget(), SLOT(adjustSize()) ); connect( m_preferred, TQ_SIGNAL(clicked()), tqApp->mainWidget(), TQ_SLOT(adjustSize()) );
connect( m_preferred, SIGNAL(clicked()), SLOT(deleteLater()) ); connect( m_preferred, TQ_SIGNAL(clicked()), TQ_SLOT(deleteLater()) );
m_oneToOne = new KPushButton( KGuiItem( i18n("Scale 100%"), "viewmag1" ), this ); m_oneToOne = new KPushButton( KGuiItem( i18n("Scale 100%"), "viewmag1" ), this );
connect( m_oneToOne, SIGNAL(clicked()), (TQObject*)videoWindow(), SLOT(resetZoom()) ); connect( m_oneToOne, TQ_SIGNAL(clicked()), (TQObject*)videoWindow(), TQ_SLOT(resetZoom()) );
connect( m_oneToOne, SIGNAL(clicked()), SLOT(deleteLater()) ); connect( m_oneToOne, TQ_SIGNAL(clicked()), TQ_SLOT(deleteLater()) );
TQBoxLayout *hbox = new TQHBoxLayout( this, 8, 6 ); TQBoxLayout *hbox = new TQHBoxLayout( this, 8, 6 );
TQBoxLayout *vbox = new TQVBoxLayout( hbox ); TQBoxLayout *vbox = new TQVBoxLayout( hbox );
@ -48,7 +48,7 @@ namespace Codeine
m_thingy->setPaletteForegroundColor( paletteBackgroundColor().dark() ); m_thingy->setPaletteForegroundColor( paletteBackgroundColor().dark() );
TQEvent e( TQEvent::Resize ); TQEvent e( TQEvent::Resize );
eventFilter( 0, &e ); eventFilter( nullptr, &e );
adjustSize(); adjustSize();
show(); show();

@ -4,18 +4,107 @@
#include "analyzer.h" #include "analyzer.h"
#include "../codeine.h" #include "../codeine.h"
#include "../debug.h" #include "../debug.h"
#include <math.h> //interpolate() #include <cmath> //interpolate()
#include <tdeglobalsettings.h>
#include <tqevent.h> //event() #include <tqevent.h> //event()
#include "xineEngine.h" #include "xineEngine.h"
#include "fht.cpp" #include "fht.cpp"
template<class W> template<class W>
Analyzer::Base<W>::Base( TQWidget *parent, uint timeout ) Analyzer::Base<W>::Base( TQWidget *parent, uint timeout, uint scopeSize )
: W( parent, "Analyzer" ) : W( parent, "Analyzer" )
, m_timeout( timeout ) , m_timeout( timeout )
, m_fht(new FHT(scopeSize))
{} {}
template<class W> void
Analyzer::Base<W>::transform(Scope &scope) //virtual
{
// This is a standard transformation that should give
// an FFT scope that has bands for pretty analyzers
// NOTE: resizing here is redundant as FHT routines only calculate FHT::size() values
// scope.resize( m_fht->size() );
float *front = &scope.front();
auto *f = new float[m_fht->size()];
m_fht->copy(&f[0], front);
m_fht->logSpectrum(front, &f[0]);
m_fht->scale(front, 1.0 / 20);
scope.resize(m_fht->size() / 2); //second half of values are rubbish
delete[] f;
}
template<class W>
void Analyzer::Base<W>::drawFrame()
{
switch(Codeine::engine()->state())
{
case Engine::Playing:
{
const Engine::Scope &theScope = Codeine::engine()->scope();
static Scope scope(512);
int i = 0;
// Convert to mono.
// The Analyzer requires mono, but xine reports interleaved PCM.
for (int x = 0; x < m_fht->size(); ++x)
{
// Average between the channels.
scope[x] = static_cast<double>(theScope[i] + theScope[i + 1]) / (2 * (1 << 15));
i += 2;
}
transform(scope);
analyze(scope);
scope.resize(m_fht->size());
break;
}
case Engine::Paused:
{
break;
}
default:
{
demo();
break;
}
}
}
template <class W>
void Analyzer::Base<W>::demo()
{
static int t = 201; //FIXME make static to namespace perhaps
if (t > 999)
{
// 0 = wasted calculations
t = 1;
}
if (t < 201)
{
Scope s(32);
const auto dt = static_cast<double>(t) / 200.0;
for (unsigned i = 0; i < s.size(); ++i)
{
s[i] = dt * (sin(M_PI + (i * M_PI) / s.size()) + 1.0);
}
analyze(s);
}
else
{
analyze(Scope(32, 0));
}
++t;
}
template<class W> bool template<class W> bool
Analyzer::Base<W>::event( TQEvent *e ) Analyzer::Base<W>::event( TQEvent *e )
{ {
@ -36,98 +125,521 @@ Analyzer::Base<W>::event( TQEvent *e )
} }
Analyzer::Base2D::Base2D( TQWidget *parent, uint timeout ) Analyzer::Base2D::Base2D( TQWidget *parent, uint timeout, uint scopeSize )
: Base<TQWidget>( parent, timeout ) : Base<TQWidget>( parent, timeout, scopeSize )
{ {
setWFlags( TQt::WNoAutoErase ); //no flicker setWFlags( TQt::WNoAutoErase ); //no flicker
connect( &m_timer, SIGNAL(timeout()), SLOT(draw()) ); connect( &m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(draw()) );
} }
void void
Analyzer::Base2D::draw() Analyzer::Base2D::resizeEvent( TQResizeEvent *e)
{ {
switch( Codeine::engine()->state() ) { m_background.resize(size());
case Engine::Playing: m_canvas.resize(size());
{ m_background.fill(backgroundColor());
const Engine::Scope &thescope = Codeine::engine()->scope(); eraseCanvas();
static Analyzer::Scope scope( Analyzer::SCOPE_SIZE );
for( int x = 0; x < Analyzer::SCOPE_SIZE; ++x )
scope[x] = double(thescope[x]) / (1<<15);
transform( scope ); TQWidget::resizeEvent(e);
analyze( scope );
scope.resize( Analyzer::SCOPE_SIZE );
bitBlt( this, 0, 0, canvas() );
break;
}
case Engine::Paused:
break;
default:
erase();
}
} }
void void Analyzer::Base2D::paletteChange(const TQPalette&)
Analyzer::Base2D::resizeEvent( TQResizeEvent* )
{ {
m_canvas.resize( size() ); m_background.fill(backgroundColor());
m_canvas.fill( colorGroup().background() ); eraseCanvas();
} }
// Author: Max Howell <max.howell@methylblue.com>, (C) 2003 // Author: Max Howell <max.howell@methylblue.com>, (C) 2003
// Copyright: See COPYING file that comes with this distribution // Copyright: See COPYING file that comes with this distribution
#include <tqpainter.h> #include <tqpainter.h>
Analyzer::Block::Block( TQWidget *parent ) Analyzer::Block::Block( TQWidget *parent )
: Analyzer::Base2D( parent, 20 ) : Analyzer::Base2D(parent, 20, 9)
, m_scope(MIN_COLUMNS)
, m_barPixmap(1, 1)
, m_topBarPixmap(WIDTH, HEIGHT)
, m_store(1 << 8, 0)
, m_fadeBars(FADE_SIZE)
, m_fadeIntensity(1 << 8, 32)
, m_fadePos(1 << 8, 50)
, m_columns(0)
, m_rows(0)
, m_y(0)
, m_step(0)
{ {
setMinimumWidth( 64 ); //-1 is padding, no drawing takes place there // -1 is padding, no drawing takes place there
setMaximumWidth( 128 ); setMinimumSize(MIN_COLUMNS * (WIDTH + 1) - 1, MIN_ROWS * (HEIGHT + 1) - 1);
setMaximumWidth(MAX_COLUMNS * (WIDTH + 1) - 1);
//TODO yes, do height for width for (auto &m_fadeBar : m_fadeBars)
{
m_fadeBar.resize(1, 1);
}
} }
void void
Analyzer::Block::transform( Analyzer::Scope &scope ) //pure virtual Analyzer::Block::transform( Analyzer::Scope &s ) //pure virtual
{ {
static FHT fht( Analyzer::SCOPE_SIZE_EXP ); for( uint x = 0; x < s.size(); ++x )
s[x] *= 2;
for( uint x = 0; x < scope.size(); ++x ) float *front = static_cast<float*>( &s.front() );
scope[x] *= 2;
float *front = static_cast<float*>( &scope.front() ); m_fht->spectrum( front );
m_fht->scale( front, 1.0 / 20 );
fht.spectrum( front ); //the second half is pretty dull, so only show it if the user has a large analyzer
fht.scale( front, 1.0 / 40 ); //by setting to m_scope.size() if large we prevent interpolation of large analyzers, this is good!
s.resize( m_scope.size() <= MAX_COLUMNS/2 ? MAX_COLUMNS/2 : m_scope.size() );
} }
void void
Analyzer::Block::analyze( const Analyzer::Scope &s ) Analyzer::Block::analyze( const Analyzer::Scope &s )
{ {
canvas()->fill( colorGroup().foreground().light() ); // y = 2 3 2 1 0 2
// . . . . # .
// . . . # # .
// # . # # # #
// # # # # # #
//
// visual aid for how this analyzer works.
// y represents the number of blanks
// y starts from the top and increases in units of blocks
// m_yscale looks similar to: { 0.7, 0.5, 0.25, 0.15, 0.1, 0 }
// if it contains 6 elements there are 5 rows in the analyzer
interpolate(s, m_scope);
// Paint the background
bitBlt(canvas(), 0, 0, background());
unsigned y;
for (unsigned x = 0; x < m_scope.size(); ++x)
{
if (m_yScale.empty())
{
return;
}
// determine y
for (y = 0; m_scope[x] < m_yScale[y]; ++y)
;
// this is opposite to what you'd think, higher than y
// means the bar is lower than y (physically)
if (static_cast<float>(y) > m_store[x])
{
y = static_cast<int>(m_store[x] += m_step);
}
else
{
m_store[x] = y;
}
// if y is lower than m_fade_pos, then the bar has exceeded the height of the fadeout
// if the fadeout is quite faded now, then display the new one
if (y <= m_fadePos[x] /*|| m_fadeIntensity[x] < FADE_SIZE / 3*/ )
{
m_fadePos[x] = y;
m_fadeIntensity[x] = FADE_SIZE;
}
if (m_fadeIntensity[x] > 0)
{
const unsigned offset = --m_fadeIntensity[x];
const unsigned y = m_y + (m_fadePos[x] * (HEIGHT + 1));
bitBlt(canvas(), x * (WIDTH + 1), y, &m_fadeBars[offset], 0, 0, WIDTH, height() - y );
}
if (m_fadeIntensity[x] == 0)
{
m_fadePos[x] = m_rows;
}
// REMEMBER: y is a number from 0 to m_rows, 0 means all blocks are glowing, m_rows means none are
bitBlt(canvas(), x * (WIDTH + 1), y * (HEIGHT + 1) + m_y, bar(), 0, y * (HEIGHT + 1));
}
for (unsigned x = 0; x < m_store.size(); ++x)
{
bitBlt(canvas(), x * (WIDTH + 1), int(m_store[x]) * (HEIGHT + 1) + m_y, &m_topBarPixmap);
}
}
static void adjustToLimits(const int &b, int &f, unsigned &amount)
{
// with a range of 0-255 and maximum adjustment of amount,
// maximise the difference between f and b
if (b < f)
{
if (b > 255 - f)
{
amount -= f;
f = 0;
}
else
{
amount -= (255 - f);
f = 255;
}
}
else
{
if (f > 255 - b)
{
amount -= f;
f = 0;
}
else
{
amount -= (255 - f);
f = 255;
}
}
}
/**
* Clever contrast function
*
* It will try to adjust the foreground color such that it contrasts well with the background
* It won't modify the hue of fg unless absolutely necessary
* @return the adjusted form of fg
*/
TQColor ensureContrast(const TQColor &bg, const TQColor &fg, unsigned _amount = 150)
{
class OutputOnExit
{
public:
explicit OutputOnExit(const TQColor &color)
: c(color)
{
}
TQPainter p( canvas() ); ~OutputOnExit()
p.setPen( colorGroup().background() ); {
int h, s, v;
c.getHsv(&h, &s, &v);
}
const double F = double(height()) / (log10( 256 ) * 1.1 /*<- max. amplitude*/); private:
const TQColor &c;
};
for( uint x = 0; x < s.size(); ++x ) // hack so I don't have to cast everywhere
//we draw the blank bit #define amount static_cast<int>(_amount)
p.drawLine( x, 0, x, int(height() - log10( s[x] * 256.0 ) * F) ); // #define STAMP debug() << (TQValueList<int>() << fh << fs << fv) << endl;
// #define STAMP1( string ) debug() << string << ": " << (TQValueList<int>() << fh << fs << fv) << endl;
// #define STAMP2( string, value ) debug() << string << "=" << value << ": " << (TQValueList<int>() << fh << fs << fv) << endl;
OutputOnExit allocateOnTheStack(fg);
int bh, bs, bv;
int fh, fs, fv;
bg.getHsv(&bh, &bs, &bv);
fg.getHsv(&fh, &fs, &fv);
int dv = abs(bv - fv);
// STAMP2( "DV", dv );
// value is the best measure of contrast
// if there is enough difference in value already, return fg unchanged
if (dv > amount)
{
return fg;
}
int ds = abs(bs - fs);
// STAMP2( "DS", ds );
// saturation is good enough too. But not as good. TODO adapt this a little
if (ds > amount)
{
return fg;
}
int dh = abs(bh - fh);
// STAMP2( "DH", dh );
if (dh > 120)
{
// a third of the colour wheel automatically guarantees contrast
// but only if the values are high enough and saturations significant enough
// to allow the colours to be visible and not be shades of grey or black
// check the saturation for the two colours is sufficient that hue alone can
// provide sufficient contrast
if (ds > amount / 2 && (bs > 125 && fs > 125))
{
// STAMP1( "Sufficient saturation difference, and hues are complimentary" );
return fg;
}
if (dv > amount / 2 && (bv > 125 && fv > 125))
{
// STAMP1( "Sufficient value difference, and hues are complimentary" );
return fg;
}
// STAMP1( "Hues are complimentary but we must modify the value or saturation of the contrasting colour" );
// but either the colours are two desaturated, or too dark
// so we need to adjust the system, although not as much
///_amount /= 2;
}
if (fs < 50 && ds < 40)
{
// low saturation on a low saturation is sad
const int tmp = 50 - fs;
fs = 50;
if (amount > tmp)
{
_amount -= tmp;
}
else
{
_amount = 0;
}
}
// test that there is available value to honor our contrast requirement
if (255 - dv < amount)
{
// we have to modify the value and saturation of fg
//adjustToLimits( bv, fv, amount );
// STAMP
// see if we need to adjust the saturation
if (amount > 0)
{
adjustToLimits(bs, fs, _amount);
}
// STAMP
// see if we need to adjust the hue
if (amount > 0)
{
fh += amount; // cycles around
}
// STAMP
return TQColor(fh, fs, fv, TQColor::Hsv);
}
// STAMP
if (fv > bv && bv > amount)
{
return TQColor( fh, fs, bv - amount, TQColor::Hsv);
}
// STAMP
if (fv < bv && fv > amount)
{
return TQColor(fh, fs, fv - amount, TQColor::Hsv);
}
// STAMP
if (fv > bv && (255 - fv > amount))
{
return TQColor(fh, fs, fv + amount, TQColor::Hsv);
}
// STAMP
if (fv < bv && (255 - bv > amount))
{
return TQColor(fh, fs, bv + amount, TQColor::Hsv);
}
// STAMP
// debug() << "Something went wrong!\n";
return TQt::blue;
#undef amount
// #undef STAMP
}
void Analyzer::Block::paletteChange(const TQPalette&)
{
const TQColor bg = palette().active().background();
const TQColor fg = ensureContrast(bg, TDEGlobalSettings::activeTitleColor());
m_topBarPixmap.fill(fg);
const double dr = 15 * double(bg.red() - fg.red()) / (m_rows * 16);
const double dg = 15 * double(bg.green() - fg.green()) / (m_rows * 16);
const double db = 15 * double(bg.blue() - fg.blue()) / (m_rows * 16);
const int r = fg.red(), g = fg.green(), b = fg.blue();
bar()->fill(bg);
TQPainter p(bar());
for (int y = 0; (uint)y < m_rows; ++y)
{
// graduate the fg color
p.fillRect(0, y * (HEIGHT + 1), WIDTH, HEIGHT, TQColor(r + int(dr * y), g + int(dg * y), b + int(db * y)));
}
{
const TQColor bg = palette().active().background().dark(112);
// make a complimentary fadebar colour
// TODO dark is not always correct, dumbo!
int h, s, v;
palette().active().background().dark(150).getHsv(&h, &s, &v);
const TQColor fg(h + 120, s, v, TQColor::Hsv);
const double dr = fg.red() - bg.red();
const double dg = fg.green() - bg.green();
const double db = fg.blue() - bg.blue();
const int r = bg.red(), g = bg.green(), b = bg.blue();
// Precalculate all fade-bar pixmaps
for (int y = 0; y < FADE_SIZE; ++y)
{
m_fadeBars[y].fill(palette().active().background());
TQPainter f(&m_fadeBars[y]);
for (int z = 0; (uint)z < m_rows; ++z)
{
const double Y = 1.0 - (log10(static_cast<float>(FADE_SIZE) - y) / log10(static_cast<float>(FADE_SIZE)));
f.fillRect(0, z * (HEIGHT + 1), WIDTH, HEIGHT, TQColor(r + int(dr * Y), g + int(dg * Y), b + int(db * Y)));
}
}
}
drawBackground();
}
void Analyzer::Block::resizeEvent(TQResizeEvent *e)
{
TQWidget::resizeEvent(e);
canvas()->resize(size());
background()->resize(size());
const uint oldRows = m_rows;
// all is explained in analyze()..
// +1 to counter -1 in maxSizes, trust me we need this!
m_columns = kMax(uint(double(width() + 1) / (WIDTH + 1)), (uint)MAX_COLUMNS);
m_rows = uint(double(height() + 1) / (HEIGHT + 1));
// this is the y-offset for drawing from the top of the widget
m_y = (height() - (m_rows * (HEIGHT + 1)) + 2) / 2;
m_scope.resize(m_columns);
if (m_rows != oldRows)
{
m_barPixmap.resize(WIDTH, m_rows * (HEIGHT + 1));
for (uint i = 0; i < FADE_SIZE; ++i )
{
m_fadeBars[i].resize(WIDTH, m_rows * (HEIGHT + 1));
}
m_yScale.resize(m_rows + 1);
const uint PRE = 1, PRO = 1; //PRE and PRO allow us to restrict the range somewhat
for (uint z = 0; z < m_rows; ++z)
{
m_yScale[z] = 1 - (log10(PRE + z) / log10(PRE + m_rows + PRO));
}
m_yScale[m_rows] = 0;
determineStep();
paletteChange( palette() );
}
else if (width() > e->oldSize().width() || height() > e->oldSize().height())
{
drawBackground();
}
analyze(m_scope);
}
void Analyzer::Block::determineStep()
{
// falltime is dependent on rowcount due to our digital resolution (ie we have boxes/blocks of pixels)
// I calculated the value 30 based on some trial and error
const double fallTime = 30 * m_rows;
// The number of milliseconds between signals with audio data is about 80,
// however, basing the step off of that value causes some undersireable
// effects in the analyzer (high-end blocks constantly appearing/disappearing).
// 44 seems to be a good mid-point.
m_step = double(m_rows * 44) / fallTime;
} }
int void Analyzer::Block::drawBackground()
Analyzer::Block::heightForWidth( int w ) const
{ {
return w / 2; const TQColor bg = palette().active().background();
const TQColor bgdark = bg.dark(112);
background()->fill(bg);
TQPainter p(background());
for (int x = 0; (uint)x < m_columns; ++x)
{
for (int y = 0; (uint)y < m_rows; ++y)
{
p.fillRect(x * (WIDTH + 1), y * (HEIGHT + 1) + m_y, WIDTH, HEIGHT, bgdark);
}
}
setErasePixmap(*background());
} }
void Analyzer::interpolate(const Scope& inVec, Scope& outVec)
{
double pos = 0.0;
const double step = (double)inVec.size() / (double)outVec.size();
for (uint i = 0; i < outVec.size(); ++i, pos += step)
{
const double error = pos - std::floor(pos);
const unsigned long offset = (unsigned long)pos;
unsigned long indexLeft = offset + 0;
if (indexLeft >= inVec.size())
{
indexLeft = inVec.size() - 1;
}
unsigned long indexRight = offset + 1;
if (indexRight >= inVec.size())
{
indexRight = inVec.size() - 1;
}
outVec[i] = inVec[indexLeft ] * (1.0 - error) +
inVec[indexRight] * error;
}
}
#include "analyzer.moc" #include "analyzer.moc"

@ -8,6 +8,7 @@
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#include "fht.h"
#include <tqpixmap.h> //stack allocated and convenience #include <tqpixmap.h> //stack allocated and convenience
#include <tqtimer.h> //stack allocated #include <tqtimer.h> //stack allocated
#include <tqwidget.h> //baseclass #include <tqwidget.h> //baseclass
@ -23,10 +24,13 @@ namespace Analyzer
uint timeout() const { return m_timeout; } uint timeout() const { return m_timeout; }
protected: protected:
Base( TQWidget*, uint ); Base( TQWidget*, uint, uint = 7 );
~Base() { delete m_fht; }
void drawFrame();
virtual void transform( Scope& ) = 0; virtual void transform( Scope& ) = 0;
virtual void analyze( const Scope& ) = 0; virtual void analyze( const Scope& ) = 0;
virtual void demo();
private: private:
virtual bool event( TQEvent* ); virtual bool event( TQEvent* );
@ -34,42 +38,91 @@ namespace Analyzer
protected: protected:
TQTimer m_timer; TQTimer m_timer;
uint m_timeout; uint m_timeout;
FHT *m_fht;
}; };
class Base2D : public Base<TQWidget> class Base2D : public Base<TQWidget>
{ {
Q_OBJECT TQ_OBJECT
public: public:
const TQPixmap *background() const { return &m_background; }
const TQPixmap *canvas() const { return &m_canvas; } const TQPixmap *canvas() const { return &m_canvas; }
private slots: private slots:
void draw(); void draw() { drawFrame(); bitBlt(this, 0, 0, canvas()); }
protected: protected:
Base2D( TQWidget*, uint timeout ); Base2D( TQWidget*, uint timeout, uint scopeSize = 7 );
TQPixmap *background() { return &m_background; }
TQPixmap *canvas() { return &m_canvas; } TQPixmap *canvas() { return &m_canvas; }
void paintEvent( TQPaintEvent* ) { if( !m_canvas.isNull() ) bitBlt( this, 0, 0, canvas() ); } void eraseCanvas()
void resizeEvent( TQResizeEvent* ); {
bitBlt(canvas(), 0, 0, background());
}
void paintEvent( TQPaintEvent* ) override { if( !m_canvas.isNull() ) bitBlt( this, 0, 0, canvas() ); }
void resizeEvent( TQResizeEvent* ) override;
void paletteChange( const TQPalette& ) override;
private: private:
TQPixmap m_background;
TQPixmap m_canvas; TQPixmap m_canvas;
}; };
class Block : public Analyzer::Base2D class Block : public Analyzer::Base2D
{ {
public: public:
Block( TQWidget* ); explicit Block( TQWidget* );
static constexpr int HEIGHT = 2;
static constexpr int FADE_SIZE = 90;
static constexpr int MIN_COLUMNS = 32;
static constexpr int MAX_COLUMNS = 256;
static constexpr int MIN_ROWS = 3;
static constexpr int WIDTH = 4;
protected: protected:
virtual void transform( Analyzer::Scope& ); virtual void transform( Analyzer::Scope& );
virtual void analyze( const Analyzer::Scope& ); virtual void analyze( const Analyzer::Scope& );
void paletteChange(const TQPalette&) override;
void resizeEvent(TQResizeEvent *) override;
void determineStep();
void drawBackground();
private:
TQPixmap *bar()
{
return &m_barPixmap;
}
// So we don't create a vector each frame.
Scope m_scope;
TQPixmap m_barPixmap;
TQPixmap m_topBarPixmap;
// Current bar heights
std::vector<float> m_store;
std::vector<float> m_yScale;
virtual int heightForWidth( int ) const; std::vector<TQPixmap> m_fadeBars;
std::vector<int> m_fadeIntensity;
std::vector<unsigned> m_fadePos;
virtual void show() {} //TODO temporary as the scope plugin causes freezes // Number of rows and columns of blocks
unsigned m_columns;
unsigned m_rows;
// y-offset from top of widget
unsigned m_y;
// rows to fall per-step
float m_step;
}; };
void interpolate(const Scope&, Scope&);
} }
#endif #endif

@ -0,0 +1,61 @@
// SPDX-FileCopyrightText: 2025 mio <stigma@disroot.org>
//
// SPDX-License-Identifier: GPL-2.0-or-later.
#include "audioView.h"
#include <tqlayout.h>
#include <tdepopupmenu.h>
#include <tdelocale.h>
#include "analyzer.h"
#include "codeineConfig.h"
namespace Codeine
{
AudioView::AudioView(TQWidget *parent, const char *name)
: TQFrame(parent, name)
{
auto *layout = new TQHBoxLayout(this);
m_analyzer = new Analyzer::Block(this);
// We subtract one from the below to remove excess padding.
// 36 blocks for the max/min height is arbitrary, but looks okay.
m_analyzer->setMaximumSize((Analyzer::Block::MAX_COLUMNS / 2) * (Analyzer::Block::WIDTH + 1) - 1,
36 * (Analyzer::Block::HEIGHT + 1) - 1);
m_analyzer->setMinimumSize(Analyzer::Block::WIDTH * Analyzer::Block::MIN_COLUMNS,
36 * (Analyzer::Block::HEIGHT + 1) - 1);
layout->addWidget(m_analyzer);
m_analyzer->setShown(config("AudioView")->readBoolEntry("showAudioAnalyzer", true));
}
AudioView::~AudioView()
{
config("AudioView")->writeEntry("showAudioAnalyzer", m_analyzer->isVisible());
config("AudioView")->sync();
}
void AudioView::contextMenuEvent(TQContextMenuEvent *e)
{
TDEPopupMenu popup;
popup.setCheckable(true);
int id = popup.insertItem(i18n("Show Analyzer"), this, TQ_SLOT(slotToggleVisibility()));
popup.setItemChecked(id, m_analyzer->isVisible());
popup.exec(e->globalPos());
}
void AudioView::slotToggleVisibility()
{
m_analyzer->setShown(!m_analyzer->isVisible());
}
}
#include "audioView.moc"

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2025 mio <stigma@disroot.org>
//
// SPDX-License-Identifier: GPL-2.0-or-later.
#ifndef CODEINE_AUDIOVIEW_H
#define CODEINE_AUDIOVIEW_H
#include <tqframe.h>
namespace Codeine
{
class AudioView : public TQFrame
{
TQ_OBJECT
public:
AudioView(TQWidget *parent, const char *name = nullptr);
~AudioView();
protected:
void contextMenuEvent(TQContextMenuEvent *e) override;
protected slots:
void slotToggleVisibility();
private:
TQWidget *m_analyzer;
};
}
#endif /* CODEINE_AUDIOVIEW_H */

@ -6,6 +6,7 @@
#include <kpushbutton.h> #include <kpushbutton.h>
#include <kstatusbar.h> #include <kstatusbar.h>
#include <kstdguiitem.h> #include <kstdguiitem.h>
#include <tqapplication.h>
#include <tqdialog.h> #include <tqdialog.h>
#include <tqhbox.h> #include <tqhbox.h>
#include <tqlabel.h> #include <tqlabel.h>
@ -69,15 +70,24 @@ public:
, m_title( TheStream::prettyTitle() ) , m_title( TheStream::prettyTitle() )
{ {
(new TQVBoxLayout( this ))->setAutoAdd( true ); (new TQVBoxLayout( this ))->setAutoAdd( true );
// Scale the image to fit within the current screen's size.
TQRect screenRect = tqApp->desktop()->availableGeometry( this );
if ( screenRect.contains( frame.rect() ) ) {
(new TQLabel( this ))->setPixmap( frame ); (new TQLabel( this ))->setPixmap( frame );
} else {
TQSize scaledSize = screenRect.size() * 0.9;
TQImage scaledImage = frame.scale( scaledSize, TQImage::ScaleMin );
(new TQLabel( this ))->setPixmap( scaledImage );
}
TQHBox *box = new TQHBox( this ); TQHBox *box = new TQHBox( this );
KPushButton *o = new KPushButton( KStdGuiItem::save(), box ); KPushButton *o = new KPushButton( KStdGuiItem::save(), box );
connect( o, SIGNAL(clicked()), SLOT(accept()) ); connect( o, TQ_SIGNAL(clicked()), TQ_SLOT(accept()) );
o = new KPushButton( KStdGuiItem::cancel(), box ); o = new KPushButton( KStdGuiItem::cancel(), box );
o->setText( i18n("Discard") ); o->setText( i18n("Discard") );
connect( o, SIGNAL(clicked()), SLOT(reject()) ); connect( o, TQ_SIGNAL(clicked()), TQ_SLOT(reject()) );
setCaption( i18n("Capture - %1").arg( time ) ); setCaption( i18n("Capture - %1").arg( time ) );
setFixedSize( sizeHint() ); setFixedSize( sizeHint() );
@ -178,7 +188,7 @@ yv12ToRgb( uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, const int w, const in
const int uv_width = w / 2; const int uv_width = w / 2;
const int uv_height = h / 2; const int uv_height = h / 2;
uchar * const rgb = new uchar[(w * h * 4)]; //qt needs a 32bit align uchar * const rgb = new uchar[(w * h * 4)]; //tqt needs a 32bit align
if( !rgb ) if( !rgb )
return 0; return 0;
@ -241,28 +251,34 @@ VideoWindow::captureFrame() const
DEBUG_BLOCK DEBUG_BLOCK
int ratio, format, w, h; int ratio, format, w, h;
if( !xine_get_current_frame( *engine(), &w, &h, &ratio, &format, NULL ) ) if (!xine_get_current_frame_s(*engine(), &w, &h, &ratio, &format, nullptr, nullptr))
return TQImage(); return TQImage();
uint8_t *yuv = new uint8_t[((w+8) * (h+1) * 2)]; int yuv_size = ((w + 8) * (h + 1)) * 2;
if( yuv == 0 ) { uint8_t *yuv = new(std::nothrow) uint8_t[yuv_size];
if (yuv == nullptr) {
Debug::error() << "Not enough memory to make screenframe!\n"; Debug::error() << "Not enough memory to make screenframe!\n";
return TQImage(); } return TQImage();
}
xine_get_current_frame( *engine(), &w, &h, &ratio, &format, yuv ); xine_get_current_frame_s(*engine(), &w, &h, &ratio, &format, yuv, &yuv_size);
// convert to yv12 if necessary // convert to yv12 if necessary
uint8_t *y = 0, *u = 0, *v = 0; uint8_t *y = nullptr;
uint8_t *u = nullptr;
uint8_t *v = nullptr;
switch( format ) switch( format )
{ {
case XINE_IMGFMT_YUY2: { case XINE_IMGFMT_YUY2: {
uint8_t *yuy2 = yuv; uint8_t *yuy2 = yuv;
yuv = new uint8_t[(w * h * 2)]; yuv = new(std::nothrow) uint8_t[(w * h * 2)];
if( yuv == 0 ) { if (yuv == nullptr) {
Debug::error() << "Not enough memory to make screenframe!\n"; Debug::error() << "Not enough memory to make screenframe!\n";
delete [] yuy2; delete [] yuy2;
return TQImage(); } return TQImage();
}
y = yuv; y = yuv;
u = yuv + w * h; u = yuv + w * h;
@ -287,7 +303,7 @@ VideoWindow::captureFrame() const
// convert to rgb // convert to rgb
uchar *rgb = yv12ToRgb( y, u, v, w, h ); uchar *rgb = yv12ToRgb( y, u, v, w, h );
TQImage frame( rgb, w, h, 32, 0, 0, TQImage::IgnoreEndian ); TQImage frame( rgb, w, h, 32, nullptr, 0, TQImage::IgnoreEndian );
delete [] yuv; delete [] yuv;
return frame; return frame;

@ -9,7 +9,7 @@ extern "C"
typedef struct xine_s xine_t; typedef struct xine_s xine_t;
} }
class TQPopupMenu; class TDESelectAction;
class TQWidget; class TQWidget;
namespace Codeine namespace Codeine
@ -22,7 +22,7 @@ namespace Codeine
void showVideoSettingsDialog( TQWidget* ); void showVideoSettingsDialog( TQWidget* );
void showXineConfigurationDialog( TQWidget*, xine_t* ); void showXineConfigurationDialog( TQWidget*, xine_t* );
void insertAspectRatioMenuItems( TQPopupMenu* ); void insertAspectRatioMenuItems( TDESelectAction* );
} }
#endif #endif

@ -24,9 +24,9 @@
FHT::FHT(int n) : FHT::FHT(int n) :
m_buf(0), m_buf(nullptr),
m_tab(0), m_tab(nullptr),
m_log(0) m_log(nullptr)
{ {
if (n < 3) { if (n < 3) {
m_num = 0; m_num = 0;
@ -175,8 +175,8 @@ void FHT::power2(float *p)
*p = (*p * *p), *p += *p, p++; *p = (*p * *p), *p += *p, p++;
for (i = 1, q = p + m_num - 2; i < (m_num / 2); i++, --q) for (i = 1, q = p + m_num - 2; i < (m_num / 2); i++, --q, p++)
*p++ = (*p * *p) + (*q * *q); *p = (*p * *p) + (*q * *q);
} }

@ -1,8 +1,8 @@
// Copyright 2005 Max Howell (max.howell@methylblue.com) // Copyright 2005 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information // See COPYING file for licensing information
#include <tdeactionclasses.h>
#include <tqpopupmenu.h> #include <tqpopupmenu.h>
#include <xine.h>
TQString i18n( const char *text ); TQString i18n( const char *text );
@ -11,15 +11,15 @@ TQString i18n( const char *text );
namespace Codeine namespace Codeine
{ {
void void
insertAspectRatioMenuItems( TQPopupMenu *menu ) insertAspectRatioMenuItems(TDESelectAction *action)
{ {
menu->insertItem( i18n( "Determine &Automatically" ), XINE_VO_ASPECT_AUTO ); TQStringList items(i18n("Determine &Automatically"));
menu->insertSeparator(); items.append(i18n("&Square (1:1)"));
menu->insertItem( i18n( "&Square (1:1)" ), XINE_VO_ASPECT_SQUARE ); items.append(i18n("&4:3"));
menu->insertItem( i18n( "&4:3" ), XINE_VO_ASPECT_4_3 ); items.append(i18n("Ana&morphic (16:9)"));
menu->insertItem( i18n( "Ana&morphic (16:9)" ), XINE_VO_ASPECT_ANAMORPHIC ); items.append(i18n("&DVB (2.11:1)"));
menu->insertItem( i18n( "&DVB (2.11:1)" ), XINE_VO_ASPECT_DVB );
menu->setItemChecked( XINE_VO_ASPECT_AUTO, true ); action->setItems(items);
action->popupMenu()->insertSeparator(1);
} }
} }

@ -11,6 +11,7 @@
#include <kcursor.h> #include <kcursor.h>
#include <tdefiledialog.h> //::open() #include <tdefiledialog.h> //::open()
#include <tdeglobalsettings.h> //::timerEvent() #include <tdeglobalsettings.h> //::timerEvent()
#include <tdepopupmenu.h>
#include <tdeio/netaccess.h> #include <tdeio/netaccess.h>
#include <ksqueezedtextlabel.h> #include <ksqueezedtextlabel.h>
#include <kstatusbar.h> #include <kstatusbar.h>
@ -18,16 +19,17 @@
#include <kurldrag.h> #include <kurldrag.h>
#include <twin.h> #include <twin.h>
#include <tqcstring.h> #include <tqcstring.h>
#include <tqdesktopwidget.h>
#include <tqevent.h> //::stateChanged() #include <tqevent.h> //::stateChanged()
#include <tqlayout.h> //ctor #include <tqlayout.h> //ctor
#include <tqpopupmenu.h> //because XMLGUI is poorly designed #include <tqpopupmenu.h> //because XMLGUI is poorly designed
#include <tqobjectlist.h> #include <tqobjectlist.h>
#include <tqwidgetstack.h>
#include "../debug.h" #include "../debug.h"
#include "../mxcl.library.h" #include "../mxcl.library.h"
#include "actions.h" #include "actions.h"
#include "analyzer.h" #include "analyzer.h"
#include "audioView.h"
#include "codeineConfig.h" #include "codeineConfig.h"
#include "extern.h" //dialog creation function definitions #include "extern.h" //dialog creation function definitions
#include "fullScreenAction.h" #include "fullScreenAction.h"
@ -48,12 +50,15 @@ extern "C"
} }
#endif #endif
constexpr auto kAspectSelectActionName = "aspect_ratio_select";
constexpr auto kAudioSelectActionName = "audio_channels_select";
constexpr auto kSubtitleSelectActionName = "subtitle_channels_select";
namespace Codeine { namespace Codeine {
/// @see codeine.h /// @see codeine.h
TQWidget *mainWindow() { return kapp->mainWidget(); } TQWidget *mainWindow() { return tdeApp->mainWidget(); }
MainWindow::MainWindow() MainWindow::MainWindow()
@ -66,10 +71,21 @@ MainWindow::MainWindow()
clearWFlags( WDestructiveClose ); //we are allocated on the stack clearWFlags( WDestructiveClose ); //we are allocated on the stack
kapp->setMainWidget( this ); tdeApp->setMainWidget( this );
m_widgetStack = new TQWidgetStack(this, "m_widgetStack");
new VideoWindow( this ); new VideoWindow( this );
setCentralWidget( videoWindow() );
m_audioView = new AudioView(this, "m_audioView");
// videoWindow() will be the initial widget.
// m_audioView is raised when no video track is present.
m_widgetStack->addWidget(videoWindow());
m_widgetStack->addWidget(m_audioView);
setCentralWidget(m_widgetStack);
setFocusProxy( videoWindow() ); // essential! See VideoWindow::event(), TQEvent::FocusOut setFocusProxy( videoWindow() ); // essential! See VideoWindow::event(), TQEvent::FocusOut
// these have no affect beccause "KDE Knows Best" FFS // these have no affect beccause "KDE Knows Best" FFS
@ -93,6 +109,9 @@ MainWindow::MainWindow()
setStandardToolBarMenuEnabled( false ); //bah to setupGUI()! setStandardToolBarMenuEnabled( false ); //bah to setupGUI()!
toolBar()->show(); //it's possible it would be hidden, but we don't want that as no UI way to show it! toolBar()->show(); //it's possible it would be hidden, but we don't want that as no UI way to show it!
m_showAnalyzer = config("MainWindow")->readBoolEntry("showAnalyzer", true);
m_analyzer->setShown(m_showAnalyzer);
// only show dvd button when playing a dvd // only show dvd button when playing a dvd
{ {
struct KdeIsTehSuck : public TQObject struct KdeIsTehSuck : public TQObject
@ -116,26 +135,27 @@ MainWindow::MainWindow()
} }
{ {
TQPopupMenu *menu = 0, *settings = static_cast<TQPopupMenu*>(factory()->container( "settings", this )); /* Disable aspect/channel menus until the stream has loaded;
int id = SubtitleChannelsMenuItemId, index = 0; * Make sure they have the same default item selected. */
TQStringList defaultItems("&Determine Automatically");
#define make_menu( name, text ) \ if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action(kAspectSelectActionName)))
menu = new TQPopupMenu( this, name ); \ {
menu->setCheckable( true ); \ aspectAction->setToolTip(i18n("Aspect Ratio"));
connect( menu, SIGNAL(activated( int )), engine(), SLOT(setStreamParameter( int )) ); \ insertAspectRatioMenuItems(aspectAction);
connect( menu, SIGNAL(aboutToShow()), SLOT(aboutToShowMenu()) ); \ aspectAction->setEnabled(false);
settings->insertItem( text, menu, id, index ); \ }
settings->setItemEnabled( id, false ); \ if (const auto audioChannelAction = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
id++, index++; {
audioChannelAction->setToolTip(i18n("Audio Channels"));
make_menu( "subtitle_channels_menu", i18n( "&Subtitles" ) ); audioChannelAction->setItems(defaultItems);
make_menu( "audio_channels_menu", i18n( "A&udio Channels" ) ); audioChannelAction->setEnabled(false);
make_menu( "aspect_ratio_menu", i18n( "Aspect &Ratio" ) ); }
#undef make_menu if (const auto subChannelAction = dynamic_cast<TDESelectAction *>(action(kSubtitleSelectActionName)))
{
Codeine::insertAspectRatioMenuItems( menu ); //so we don't have to include xine.h here subChannelAction->setToolTip(i18n("Subtitles"));
subChannelAction->setItems(defaultItems);
settings->insertSeparator( index ); subChannelAction->setEnabled(false);
}
} }
TQObjectList *list = toolBar()->queryList( "TDEToolBarButton" ); TQObjectList *list = toolBar()->queryList( "TDEToolBarButton" );
@ -153,13 +173,13 @@ MainWindow::MainWindow()
KXMLGUIClient::stateChanged( "empty" ); KXMLGUIClient::stateChanged( "empty" );
TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
if( args->count() || args->isSet( "play-dvd" ) || kapp->isRestored() ) if( args->count() || args->isSet( "play-dvd" ) || tdeApp->isRestored() )
//we need to resize the window, so we can't show the window yet //we need to resize the window, so we can't show the window yet
init(); init();
else { else {
//"faster" startup //"faster" startup
//TODO if we have a size stored for this video, do the "faster" route //TODO if we have a size stored for this video, do the "faster" route
TQTimer::singleShot( 0, this, SLOT(init()) ); TQTimer::singleShot( 0, this, TQ_SLOT(init()) );
TQApplication::setOverrideCursor( KCursor::waitCursor() ); } TQApplication::setOverrideCursor( KCursor::waitCursor() ); }
} }
@ -168,11 +188,15 @@ MainWindow::init()
{ {
DEBUG_BLOCK DEBUG_BLOCK
connect( engine(), SIGNAL(statusMessage( const TQString& )), this, SLOT(engineMessage( const TQString& )) ); connect( engine(), TQ_SIGNAL(statusMessage( const TQString& )), this, TQ_SLOT(engineMessage( const TQString& )) );
connect( engine(), SIGNAL(stateChanged( Engine::State )), this, SLOT(engineStateChanged( Engine::State )) ); connect( engine(), TQ_SIGNAL(stateChanged( Engine::State )), this, TQ_SLOT(engineStateChanged( Engine::State )) );
connect( engine(), SIGNAL(channelsChanged( const TQStringList& )), this, SLOT(setChannels( const TQStringList& )) ); connect( engine(), TQ_SIGNAL(titleChanged( const TQString& )), m_titleLabel, TQ_SLOT(setText( const TQString& )) );
connect( engine(), SIGNAL(titleChanged( const TQString& )), m_titleLabel, SLOT(setText( const TQString& )) ); connect( m_positionSlider, TQ_SIGNAL(valueChanged( int )), this, TQ_SLOT(showTime( int )) );
connect( m_positionSlider, SIGNAL(valueChanged( int )), this, SLOT(showTime( int )) );
connect(engine(), TQ_SIGNAL(audioChannelsChanged(const TQStringList &)),
this, TQ_SLOT(setAudioChannels(const TQStringList &)));
connect(engine(), TQ_SIGNAL(subtitleChannelsChanged(const TQStringList &)),
this, TQ_SLOT(setSubtitleChannels(const TQStringList &)));
if( !engine()->init() ) { if( !engine()->init() ) {
KMessageBox::error( this, i18n( KMessageBox::error( this, i18n(
@ -183,12 +207,12 @@ MainWindow::init()
//would be dangerous for these to65535 happen before the videoWindow() is initialised //would be dangerous for these to65535 happen before the videoWindow() is initialised
setAcceptDrops( true ); setAcceptDrops( true );
connect( m_positionSlider, SIGNAL(sliderReleased( uint )), engine(), SLOT(seek( uint )) ); connect( m_positionSlider, TQ_SIGNAL(sliderReleased( uint )), engine(), TQ_SLOT(seek( uint )) );
connect( statusBar(), SIGNAL(messageChanged( const TQString& )), engine(), SLOT(showOSD( const TQString& )) ); connect( statusBar(), TQ_SIGNAL(messageChanged( const TQString& )), engine(), TQ_SLOT(showOSD( const TQString& )) );
TQApplication::restoreOverrideCursor(); TQApplication::restoreOverrideCursor();
if( !kapp->isRestored() ) { if( !tdeApp->isRestored() ) {
TDECmdLineArgs &args = *TDECmdLineArgs::parsedArgs(); TDECmdLineArgs &args = *TDECmdLineArgs::parsedArgs();
if (args.isSet( "play-dvd" )) if (args.isSet( "play-dvd" ))
open( "dvd:/" ); open( "dvd:/" );
@ -221,6 +245,9 @@ MainWindow::~MainWindow()
bool bool
MainWindow::queryExit() MainWindow::queryExit()
{ {
config("MainWindow")->writeEntry("showAnalyzer", m_showAnalyzer);
config("MainWindow")->sync();
if( toggleAction( "fullscreen" )->isChecked() ) { if( toggleAction( "fullscreen" )->isChecked() ) {
// there seems to be no other way to stop TDEMainWindow // there seems to be no other way to stop TDEMainWindow
// saving the window state without any controls // saving the window state without any controls
@ -246,26 +273,35 @@ MainWindow::setupActions()
TDEActionCollection * const ac = actionCollection(); TDEActionCollection * const ac = actionCollection();
KStdAction::quit( kapp, SLOT(quit()), ac ); KStdAction::quit( tdeApp, TQ_SLOT(quit()), ac );
KStdAction::open( this, SLOT(playMedia()), ac, "play_media" )->setText( i18n("Play &Media...") ); KStdAction::open( this, TQ_SLOT(playMedia()), ac, "play_media" )->setText( i18n("Play &Media...") );
connect( new FullScreenAction( this, ac ), SIGNAL(toggled( bool )), SLOT(fullScreenToggled( bool )) ); connect( new FullScreenAction( this, ac ), TQ_SIGNAL(toggled( bool )), TQ_SLOT(fullScreenToggled( bool )) );
new PlayAction( this, TQ_SLOT(play()), ac );
new TDEAction( i18n("Stop"), "media-playback-stop", Key_S, engine(), TQ_SLOT(stop()), ac, "stop" );
new TDEToggleAction( i18n("Record"), "player_record", CTRL + Key_R, engine(), TQ_SLOT(record()), ac, "record" );
new TDEAction( i18n("Reset Video Scale"), "viewmag1", Key_Equal, videoWindow(), TQ_SLOT(resetZoom()), ac, "reset_zoom" );
new TDEAction( i18n("Media Information"), "messagebox_info", Key_I, this, TQ_SLOT(streamInformation()), ac, "information" );
new TDEAction( i18n("Menu Toggle"), "media-optical-dvd-unmounted", Key_R, engine(), TQ_SLOT(toggleDVDMenu()), ac, "toggle_dvd_menu" );
new TDEAction( i18n("&Capture Frame"), "frame_image", Key_C, this, TQ_SLOT(captureFrame()), ac, "capture_frame" );
new PlayAction( this, SLOT(play()), ac ); new TDEAction( i18n("Video Settings..."), "configure", Key_V, this, TQ_SLOT(configure()), ac, "video_settings" );
new TDEAction( i18n("Stop"), "media-playback-stop", Key_S, engine(), SLOT(stop()), ac, "stop" ); new TDEAction( i18n("Configure xine..."), "configure", 0, this, TQ_SLOT(configure()), ac, "xine_settings" );
new TDEToggleAction( i18n("Record"), "player_record", CTRL + Key_R, engine(), SLOT(record()), ac, "record" ); (new KWidgetAction( m_positionSlider, i18n("Position Slider"), nullptr, nullptr, nullptr, ac, "position_slider" ))->setAutoSized( true );
new TDEAction( i18n("Reset Video Scale"), "viewmag1", Key_Equal, videoWindow(), SLOT(resetZoom()), ac, "reset_zoom" ); const auto audioSelectAction = new TDESelectAction(i18n("A&udio Channels"), 0, ac, kAudioSelectActionName);
new TDEAction( i18n("Media Information"), "messagebox_info", Key_I, this, SLOT(streamInformation()), ac, "information" ); connect(audioSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
new TDEAction( i18n("Menu Toggle"), "media-optical-dvd-unmounted", Key_R, engine(), SLOT(toggleDVDMenu()), ac, "media-optical-dvd-unmounted" );
new TDEAction( i18n("&Capture Frame"), "frame_image", Key_C, this, SLOT(captureFrame()), ac, "capture_frame" );
new TDEAction( i18n("Video Settings..."), "configure", Key_V, this, SLOT(configure()), ac, "video_settings" ); const auto subSelectAction = new TDESelectAction(i18n("&Subtitles"), 0, ac, kSubtitleSelectActionName);
new TDEAction( i18n("Configure xine..."), "configure", 0, this, SLOT(configure()), ac, "xine_settings" ); connect(subSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
(new KWidgetAction( m_positionSlider, i18n("Position Slider"), 0, 0, 0, ac, "position_slider" ))->setAutoSized( true ); const auto aspectSelectAction = new TDESelectAction(i18n("Aspect &Ratio"), 0, ac, kAspectSelectActionName);
connect(aspectSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
new VolumeAction( toolBar(), ac ); m_volumeAction = new VolumeAction( toolBar(), ac );
} }
void void
@ -282,6 +318,24 @@ MainWindow::readProperties( TDEConfig *config )
engine()->play( config->readNumEntry( "time" ) ); engine()->play( config->readNumEntry( "time" ) );
} }
void
MainWindow::contextMenuEvent(TQContextMenuEvent *ev)
{
TQRect statusBarRect(mapTo(this, statusBar()->pos()), statusBar()->size());
if (statusBarRect.contains(ev->pos()) && TheStream::hasVideo())
{
ev->accept();
TDEPopupMenu menu;
menu.setCheckable(true);
int id = menu.insertItem(i18n("Show Analyzer"), this, TQ_SLOT(toggleAnalyzer()));
menu.setItemChecked(id, m_analyzer->isVisible());
menu.exec(ev->globalPos());
}
}
void void
MainWindow::timerEvent( TQTimerEvent* ) MainWindow::timerEvent( TQTimerEvent* )
{ {
@ -331,6 +385,13 @@ MainWindow::showTime( int pos )
m_timeLabel->setText( time ); m_timeLabel->setText( time );
} }
void
MainWindow::toggleAnalyzer()
{
m_showAnalyzer = !m_showAnalyzer;
m_analyzer->setShown(m_showAnalyzer);
}
void void
MainWindow::engineMessage( const TQString &message ) MainWindow::engineMessage( const TQString &message )
{ {
@ -381,7 +442,7 @@ MainWindow::load( const KURL &url )
if (url.protocol() == "media") { if (url.protocol() == "media") {
#define UDS_LOCAL_PATH (72 | TDEIO::UDS_STRING) #define UDS_LOCAL_PATH (72 | TDEIO::UDS_STRING)
TDEIO::UDSEntry e; TDEIO::UDSEntry e;
if (!TDEIO::NetAccess::stat( url, e, 0 )) if (!TDEIO::NetAccess::stat( url, e, nullptr ))
MessageBox::sorry( "There was an internal error with the media slave..." ); MessageBox::sorry( "There was an internal error with the media slave..." );
else { else {
TDEIO::UDSEntry::ConstIterator end = e.end(); TDEIO::UDSEntry::ConstIterator end = e.end();
@ -507,7 +568,6 @@ show_toolbar:
//we aren't managed by mainWindow when at FullScreen //we aren't managed by mainWindow when at FullScreen
videoWindow()->move( 0, 0 ); videoWindow()->move( 0, 0 );
videoWindow()->resize( ((TQWidget*)o)->size() ); videoWindow()->resize( ((TQWidget*)o)->size() );
videoWindow()->lower();
} }
if (o == m_toolbar) if (o == m_toolbar)
@ -564,14 +624,12 @@ MainWindow::fullScreenToggled( bool isFullScreen )
statusBar()->setHidden( isFullScreen ); statusBar()->setHidden( isFullScreen );
setMouseTracking( isFullScreen ); /// @see mouseMoveEvent() setMouseTracking( isFullScreen ); /// @see mouseMoveEvent()
m_widgetStack->setMouseTracking(isFullScreen);
if (isFullScreen) if (isFullScreen)
s_handler = new FullScreenToolBarHandler( this ); s_handler = new FullScreenToolBarHandler( this );
else else
delete s_handler; delete s_handler;
// prevent videoWindow() moving around when mouse moves
setCentralWidget( isFullScreen ? 0 : videoWindow() );
} }
void void
@ -593,54 +651,49 @@ MainWindow::streamInformation()
} }
void void
MainWindow::setChannels( const TQStringList &channels ) MainWindow::setAudioChannels(const TQStringList &channels) const
{ {
DEBUG_FUNC_INFO DEBUG_FUNC_INFO
//TODO -1 = auto /* Xine uses -1 and -2 to indicate that a channel should be determined automatically or
* turned off. TDESelectAction inserts items starting from index 0, so we add 2 to the
* channel returned from TheStream to match. */
TQStringList::ConstIterator it = channels.begin(); if (const auto audioSelection = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
{
TQPopupMenu *menu = (TQPopupMenu*)child( (*it).latin1() ); TQStringList audioChannels(channels);
menu->clear(); audioChannels.prepend("&Determine Automatically");
audioChannels.prepend("&Off");
menu->insertItem( i18n("&Determine Automatically"), 1 ); audioSelection->setItems(audioChannels);
menu->insertSeparator(); audioSelection->popupMenu()->insertSeparator(2);
audioSelection->setCurrentItem(TheStream::audioChannel() + 2);
//the id is crucial, since the slot this menu is connected to requires audioSelection->setEnabled(channels.count());
//that information to set the correct channel }
//NOTE we subtract 2 in xineEngine because TQMenuData doesn't allow negative id else
int id = 2; {
++it; Debug::error() << "Failed to update the audio channels (selection menu not found)" << endl;
for( TQStringList::ConstIterator const end = channels.end(); it != end; ++it, ++id ) }
menu->insertItem( *it, id );
menu->insertSeparator();
menu->insertItem( i18n("&Off"), 0 );
id = channels.first() == "subtitle_channels_menu" ? SubtitleChannelsMenuItemId : AudioChannelsMenuItemId;
MainWindow::menu( "settings" )->setItemEnabled( id, channels.count() > 1 );
} }
void void
MainWindow::aboutToShowMenu() MainWindow::setSubtitleChannels(const TQStringList &channels) const
{ {
TQPopupMenu *menu = (TQPopupMenu*)sender(); DEBUG_FUNC_INFO
TQCString name( sender() ? sender()->name() : 0 );
// uncheck all items first
for( uint x = 0; x < menu->count(); ++x )
menu->setItemChecked( menu->idAt( x ), false );
int id;
if( name == "subtitle_channels_menu" )
id = TheStream::subtitleChannel() + 2;
else if( name == "audio_channels_menu" )
id = TheStream::audioChannel() + 2;
else
id = TheStream::aspectRatio();
menu->setItemChecked( id, true ); if (const auto subSelection = dynamic_cast<TDESelectAction *>(action(kSubtitleSelectActionName)))
{
TQStringList subChannels(channels);
subChannels.prepend("&Determine Automatically");
subChannels.prepend("&Off");
subSelection->setItems(subChannels);
subSelection->popupMenu()->insertSeparator(2);
subSelection->setCurrentItem(TheStream::subtitleChannel() + 2);
subSelection->setEnabled(channels.count());
}
else
{
Debug::error() << "Failed to update the subtitle channels (selection menu not found)" << endl;
}
} }
void void
@ -681,10 +734,10 @@ MainWindow::keyPressEvent( TQKeyEvent *e )
} }
TQPopupMenu* TQPopupMenu*
MainWindow::menu( const char *name ) MainWindow::menu( const TQString& name )
{ {
// KXMLGUI is "really good". // KXMLGUI is "really good".
return static_cast<TQPopupMenu*>(factory()->container( name, this )); return dynamic_cast<TQPopupMenu*>(factory()->container( name, this ));
} }
@ -692,7 +745,7 @@ MainWindow::menu( const char *name )
TDEActionCollection* TDEActionCollection*
actionCollection() actionCollection()
{ {
return static_cast<MainWindow*>(kapp->mainWidget())->actionCollection(); return static_cast<MainWindow*>(tdeApp->mainWidget())->actionCollection();
} }
/// Convenience class for other classes that need access to the actions /// Convenience class for other classes that need access to the actions
@ -701,17 +754,23 @@ action( const char *name )
{ {
#define QT_FATAL_ASSERT #define QT_FATAL_ASSERT
MainWindow *mainWindow = 0; MainWindow *mainWindow = nullptr;
TDEActionCollection *actionCollection = 0; TDEActionCollection *actionCollection = nullptr;
TDEAction *action = 0; TDEAction *action = nullptr;
if( mainWindow = (MainWindow*)kapp->mainWidget() ) mainWindow = dynamic_cast<MainWindow *>(tdeApp->mainWidget());
if( actionCollection = mainWindow->actionCollection() ) if (mainWindow)
action = actionCollection->action( name ); {
actionCollection = mainWindow->actionCollection();
if (actionCollection)
{
action = actionCollection->action(name);
}
}
Q_ASSERT( mainWindow ); Q_ASSERT(mainWindow);
Q_ASSERT( actionCollection ); Q_ASSERT(actionCollection);
Q_ASSERT( action ); Q_ASSERT(action);
return action; return action;
} }

@ -11,13 +11,17 @@ class KURL;
class TQLabel; class TQLabel;
class TQPopupMenu; class TQPopupMenu;
class TQSlider; class TQSlider;
class TQWidgetStack;
class VolumeAction;
namespace Codeine namespace Codeine
{ {
class AudioView;
class MainWindow : public TDEMainWindow class MainWindow : public TDEMainWindow
{ {
Q_OBJECT TQ_OBJECT
MainWindow(); MainWindow();
~MainWindow(); ~MainWindow();
@ -39,9 +43,10 @@ namespace Codeine
void engineStateChanged( Engine::State ); void engineStateChanged( Engine::State );
void init(); void init();
void showTime( int = -1 ); void showTime( int = -1 );
void setChannels( const TQStringList& );
void aboutToShowMenu();
void fullScreenToggled( bool ); void fullScreenToggled( bool );
void setAudioChannels(const TQStringList&) const;
void setSubtitleChannels(const TQStringList&) const;
void toggleAnalyzer();
private: private:
void setupActions(); void setupActions();
@ -49,8 +54,9 @@ namespace Codeine
bool load( const KURL& ); bool load( const KURL& );
bool open( const KURL& ); bool open( const KURL& );
TQPopupMenu *menu( const char *name ); TQPopupMenu *menu(const TQString&);
void contextMenuEvent(TQContextMenuEvent *event) override;
virtual void timerEvent( TQTimerEvent* ); virtual void timerEvent( TQTimerEvent* );
virtual void dragEnterEvent( TQDragEnterEvent* ); virtual void dragEnterEvent( TQDragEnterEvent* );
virtual void dropEvent( TQDropEvent* ); virtual void dropEvent( TQDropEvent* );
@ -65,6 +71,13 @@ namespace Codeine
TQLabel *m_timeLabel; TQLabel *m_timeLabel;
TQLabel *m_titleLabel; TQLabel *m_titleLabel;
TQWidget *m_analyzer; TQWidget *m_analyzer;
AudioView *m_audioView;
TQWidgetStack *m_widgetStack;
VolumeAction *m_volumeAction;
// Keep track of Analyzer visibility separately so swapping between
// Video & Audio correctly restores the state without re-reading the config.
bool m_showAnalyzer;
//undefined //undefined
MainWindow( const MainWindow& ); MainWindow( const MainWindow& );

@ -25,7 +25,7 @@ namespace Codeine {
PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog ) PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog )
: TQDialog( parent ) : TQDialog( parent )
{ {
setCaption( kapp->makeStdCaption( i18n("Play Media") ) ); setCaption( tdeApp->makeStdCaption( i18n("Play Media") ) );
TQSignalMapper *mapper = new TQSignalMapper( this ); TQSignalMapper *mapper = new TQSignalMapper( this );
TQWidget *o, *closeButton = new KPushButton( KStdGuiItem::close(), this ); TQWidget *o, *closeButton = new KPushButton( KStdGuiItem::close(), this );
@ -37,19 +37,19 @@ PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog )
//TODO use the kguiItems from the actions //TODO use the kguiItems from the actions
mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play File..."), "folder" ), this ), FILE ); mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play File..."), "folder" ), this ), FILE );
connect( o, SIGNAL(clicked()), mapper, SLOT(map()) ); connect( o, TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()) );
grid->TQLayout::add( o ); grid->TQLayout::add( o );
mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play VCD"), "media-optical-cdaudio-unmounted" ), this ), VCD ); mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play VCD"), "media-optical-cdaudio-unmounted" ), this ), VCD );
connect( o, SIGNAL(clicked()), mapper, SLOT(map()) ); connect( o, TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()) );
grid->TQLayout::add( o ); grid->TQLayout::add( o );
mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play DVD"), "media-optical-dvd-unmounted" ), this ), DVD ); mapper->setMapping( o = new KPushButton( KGuiItem( i18n("Play DVD"), "media-optical-dvd-unmounted" ), this ), DVD );
connect( o, SIGNAL(clicked()), mapper, SLOT(map()) ); connect( o, TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()) );
grid->TQLayout::add( o ); grid->TQLayout::add( o );
mapper->setMapping( closeButton, TQDialog::Rejected ); mapper->setMapping( closeButton, TQDialog::Rejected );
connect( closeButton, SIGNAL(clicked()), mapper, SLOT(map()) ); connect( closeButton, TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()) );
createRecentFileWidget( vbox ); createRecentFileWidget( vbox );
@ -59,12 +59,12 @@ PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog )
if( be_welcome_dialog ) { if( be_welcome_dialog ) {
TQWidget *w = new KPushButton( KStdGuiItem::quit(), this ); TQWidget *w = new KPushButton( KStdGuiItem::quit(), this );
hbox->addWidget( w ); hbox->addWidget( w );
connect( w, SIGNAL(clicked()), kapp, SLOT(quit()) ); connect( w, TQ_SIGNAL(clicked()), tdeApp, TQ_SLOT(quit()) );
} }
hbox->addWidget( closeButton ); hbox->addWidget( closeButton );
connect( mapper, SIGNAL(mapped( int )), SLOT(done( int )) ); connect( mapper, TQ_SIGNAL(mapped( int )), TQ_SLOT(done( int )) );
} }
void void
@ -93,12 +93,12 @@ PlayDialog::createRecentFileWidget( TQBoxLayout *layout )
for( KURL::List::ConstIterator it = urls.begin(), end = urls.end(); it != end; ++it ) { for( KURL::List::ConstIterator it = urls.begin(), end = urls.end(); it != end; ++it ) {
const TQString fileName = (*it).fileName(); const TQString fileName = (*it).fileName();
new TDEListViewItem( lv, 0, (*it).url(), fileName.isEmpty() ? (*it).prettyURL() : fileName ); new TDEListViewItem( lv, nullptr, (*it).url(), fileName.isEmpty() ? (*it).prettyURL() : fileName );
} }
if( lv->childCount() ) { if( lv->childCount() ) {
layout->addWidget( lv, 1 ); layout->addWidget( lv, 1 );
connect( lv, SIGNAL(executed( TQListViewItem* )), SLOT(done( TQListViewItem* )) ); connect( lv, TQ_SIGNAL(executed( TQListViewItem* )), TQ_SLOT(done( TQListViewItem* )) );
} }
else else
delete lv; delete lv;

@ -15,7 +15,7 @@ namespace Codeine
{ {
class PlayDialog : public TQDialog class PlayDialog : public TQDialog
{ {
Q_OBJECT TQ_OBJECT
public: public:
PlayDialog( TQWidget*, bool show_welcome_dialog = false ); PlayDialog( TQWidget*, bool show_welcome_dialog = false );

@ -14,7 +14,7 @@
using Codeine::Slider; using Codeine::Slider;
Slider *Slider::s_instance = 0; Slider *Slider::s_instance = nullptr;
Slider::Slider( TQWidget *parent, uint max ) Slider::Slider( TQWidget *parent, uint max )
@ -106,8 +106,8 @@ static inline TQString timeAsString( const int s )
void void
Slider::setValue( int newValue ) Slider::setValue( int newValue )
{ {
static TQLabel *w1 = 0; static TQLabel *w1 = nullptr;
static TQLabel *w2 = 0; static TQLabel *w2 = nullptr;
if (!w1) { if (!w1) {
w1 = new TQLabel( this ); w1 = new TQLabel( this );

@ -10,7 +10,7 @@ namespace Codeine
{ {
class Slider : public TQSlider class Slider : public TQSlider
{ {
Q_OBJECT TQ_OBJECT
public: public:
static Slider *instance() { return s_instance; } static Slider *instance() { return s_instance; }

@ -13,9 +13,12 @@
#include <tqlabel.h> #include <tqlabel.h>
#include <tqpopupmenu.h> #include <tqpopupmenu.h>
#include <tqslider.h> #include <tqslider.h>
#include <tqwidgetstack.h>
#include "audioView.h"
#include "theStream.h" #include "theStream.h"
#include "videoSettings.h" //FIXME unfortunate #include "videoSettings.h" //FIXME unfortunate
#include "xineEngine.h" #include "xineEngine.h"
#include "volumeAction.h"
//TODO do in Sconstruct //TODO do in Sconstruct
@ -62,9 +65,8 @@ MainWindow::engineStateChanged( Engine::State state )
toggleAction( "play" )->setChecked( state == Playing ); toggleAction( "play" )->setChecked( state == Playing );
//FIXME bad design to do this way //FIXME bad design to do this way
TQSlider *volume = (TQSlider*)toolBar()->child( "volume" ); m_volumeAction->setVolume(engine()->volume());
if (volume) m_volumeAction->setMuted(engine()->isMuted());
volume->setValue( engine()->volume() );
} }
@ -91,19 +93,32 @@ MainWindow::engineStateChanged( Engine::State state )
file_menu->changeItem( play_id, item.iconSet(), item.text() ); file_menu->changeItem( play_id, item.iconSet(), item.text() );
file_menu->setItemChecked( play_id, false ); file_menu->setItemChecked( play_id, false );
settings_menu->setItemEnabled( AspectRatioMenuItemId, state & (Playing | Paused) && TheStream::hasVideo() ); if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action("aspect_ratio_select")))
{
// set correct aspect ratio aspectAction->setEnabled((state & (Playing | Paused)) && TheStream::hasVideo());
if( state == Loaded ) if (state == Loaded)
static_cast<TQPopupMenu*>(child( "aspect_ratio_menu" ))->setItemChecked( TheStream::aspectRatio(), true ); {
aspectAction->setCurrentItem(TheStream::aspectRatio());
}
}
} }
/// update statusBar /// update statusBar
{ {
using namespace Engine; using namespace Engine;
m_analyzer->setShown( state & (Playing | Paused) && TheStream::hasAudio() ); m_analyzer->setShown(m_showAnalyzer && (TheStream::hasVideo() && TheStream::hasAudio()));
m_timeLabel->setShown( state & (Playing | Paused) ); m_timeLabel->setShown(state & (Playing | Paused));
}
// Update the current widget shown.
if (TheStream::hasVideo() || (state & (Engine::Empty)))
{
m_widgetStack->raiseWidget(videoWindow());
}
else if (TheStream::hasAudio())
{
m_widgetStack->raiseWidget(m_audioView);
} }
@ -121,6 +136,8 @@ MainWindow::engineStateChanged( Engine::State state )
case Engine::Paused: case Engine::Paused:
m_positionSlider->setEnabled( TheStream::canSeek() ); m_positionSlider->setEnabled( TheStream::canSeek() );
break; break;
default:
break;
} }
@ -161,6 +178,8 @@ MainWindow::engineStateChanged( Engine::State state )
case Engine::TrackEnded: case Engine::TrackEnded:
m_titleLabel->setText( TheStream::prettyTitle() ); m_titleLabel->setText( TheStream::prettyTitle() );
break; break;
default:
break;
} }
@ -188,6 +207,8 @@ MainWindow::engineStateChanged( Engine::State state )
case Engine::Playing: case Engine::Playing:
toolBar()->hide(); toolBar()->hide();
break; break;
default:
break;
} }
} }
} }

@ -37,7 +37,7 @@ public:
setTickmarks( TQSlider::Below ); setTickmarks( TQSlider::Below );
setTickInterval( 65536 / 4 ); setTickInterval( 65536 / 4 );
setMinimumWidth( fontMetrics().width( name ) * 3 ); setMinimumWidth( fontMetrics().width( name ) * 3 );
connect( this, SIGNAL(valueChanged( int )), Codeine::engine(), SLOT(setStreamParameter( int )) ); connect( this, TQ_SIGNAL(valueChanged( int )), Codeine::engine(), TQ_SLOT(setStreamParameter( int )) );
} }
virtual void mousePressEvent( TQMouseEvent *e ) virtual void mousePressEvent( TQMouseEvent *e )

@ -54,7 +54,7 @@ VideoWindow::initVideo()
m_displayRatio = w / h; m_displayRatio = w / h;
} }
connect( &m_timer, SIGNAL(timeout()), SLOT(hideCursor()) ); connect( &m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(hideCursor()) );
XUnlockDisplay( X::d ); XUnlockDisplay( X::d );
} }
@ -139,9 +139,12 @@ VideoWindow::contextMenuEvent( TQContextMenuEvent *e )
popup.insertSeparator(); popup.insertSeparator();
if( TheStream::url().protocol() == "dvd" ) if (TheStream::url().protocol() == "dvd")
action( "toggle_dvd_menu" )->plug( &popup ), {
action("toggle_dvd_menu")->plug(&popup);
popup.insertSeparator(); popup.insertSeparator();
}
if( !((TDEToggleAction*)actionCollection()->action( "fullscreen" ))->isChecked() ) if( !((TDEToggleAction*)actionCollection()->action( "fullscreen" ))->isChecked() )
action( "reset_zoom" )->plug( &popup ); action( "reset_zoom" )->plug( &popup );
action( "capture_frame" )->plug( &popup ); action( "capture_frame" )->plug( &popup );
@ -223,11 +226,6 @@ VideoWindow::event( TQEvent *e )
stop(); stop();
return false; return false;
case VideoWindow::ExposeEvent:
//see VideoWindow::x11Event()
return true;
// Xlib.h sucks fucking balls!!!!11!!1! // Xlib.h sucks fucking balls!!!!11!!1!
#undef KeyPress #undef KeyPress
case TQEvent::KeyPress: { case TQEvent::KeyPress: {
@ -259,7 +257,7 @@ VideoWindow::event( TQEvent *e )
xine_event_t xineEvent; xine_event_t xineEvent;
xineEvent.type = keyCode; xineEvent.type = keyCode;
xineEvent.data = NULL; xineEvent.data = nullptr;
xineEvent.data_length = 0; xineEvent.data_length = 0;
xine_event_send( m_stream, &xineEvent ); xine_event_send( m_stream, &xineEvent );

@ -1,12 +1,15 @@
// (C) 2005 Max Howell (max.howell@methylblue.com) // (C) 2005 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information // See COPYING file for licensing information
#include <kiconloader.h>
#include <tdelocale.h> #include <tdelocale.h>
#include <tdetoolbar.h> #include <tdetoolbar.h>
#include <tqevent.h> #include <tqevent.h>
#include <tqlabel.h> #include <tqlabel.h>
#include <tqlayout.h> #include <tqlayout.h>
#include <tqslider.h> #include <tqslider.h>
#include <tqtoolbutton.h>
#include <tqtooltip.h>
#include "../debug.h" #include "../debug.h"
#include "volumeAction.h" #include "volumeAction.h"
@ -20,37 +23,77 @@ public:
VolumeSlider( TQWidget *parent ) VolumeSlider( TQWidget *parent )
: TQFrame( parent ) : TQFrame( parent )
{ {
slider = new TQSlider( TQt::Vertical, this, "volume" ); slider = new TQSlider(TQt::Vertical, this, "volume");
label = new TQLabel( this ); label = new TQLabel(this);
TQBoxLayout *lay = new TQVBoxLayout( this ); mute = new TQToolButton(this, "volume_slider_mute");
lay->addWidget( slider, 0, TQt::AlignHCenter ); mute->setAutoRaise(true);
lay->addWidget( label, 0, TQt::AlignHCenter ); mute->setToggleButton(true);
lay->setMargin( 4 ); TQToolTip::add(mute, i18n("Toggle Mute"));
TQBoxLayout *lay = new TQVBoxLayout(this);
lay->addWidget(slider, 0, TQt::AlignHCenter);
lay->addWidget(label, 0, TQt::AlignHCenter);
lay->addWidget(mute, 0, TQt::AlignHCenter);
lay->setMargin(4);
slider->setRange( 0, 100 ); slider->setRange( 0, 100 );
setFrameStyle( TQFrame::Plain | TQFrame::Box ); setFrameStyle( TQFrame::Plain | TQFrame::Box );
setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ); setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred );
// Test for icon support
const char* mutedIcons[] = { "audio-volume-muted", "player_mute", "mute" };
bool iconFound = false;
for (size_t i = 0; i < (sizeof(mutedIcons) / sizeof(*mutedIcons)); ++i)
{
if (!TDEGlobal::iconLoader()->iconPath(mutedIcons[i], TDEIcon::Toolbar, true).isNull())
{
mute->setIconSet(TDEGlobal::iconLoader()->loadIconSet(mutedIcons[i], TDEIcon::Toolbar));
iconFound = true;
break;
}
}
if (!iconFound)
{
mute->setAutoRaise(false);
mute->setText(i18n("Mute"));
}
// Calculate width required for max label size
label->setText( "100%" );
adjustSize();
requiredWidth = width();
hide(); hide();
} }
TQToolButton *mute;
TQLabel *label; TQLabel *label;
TQSlider *slider; TQSlider *slider;
int requiredWidth;
void setMuted(bool muted)
{
// Behave correctly when VolumeAction's "setMuted" slot is invoked.
mute->setDown(muted);
}
}; };
VolumeAction::VolumeAction( TDEToolBar *bar, TDEActionCollection *ac ) VolumeAction::VolumeAction( TDEToolBar *bar, TDEActionCollection *ac )
: TDEToggleAction( i18n("Volume"), "volume", TQt::Key_1, 0, 0, ac, "volume" ) : TDEToggleAction( i18n("Volume"), "volume", TQt::Key_1, nullptr, nullptr, ac, "volume" )
, m_anchor( 0 ) , m_anchor( nullptr )
{ {
m_widget = new VolumeSlider( bar->topLevelWidget() ); m_widget = new VolumeSlider( bar->topLevelWidget() );
connect( this, SIGNAL(toggled( bool )), SLOT(toggled( bool )) ); connect(this, TQ_SIGNAL(toggled(bool)), TQ_SLOT(toggled(bool)));
connect( m_widget->slider, SIGNAL(sliderMoved( int )), SLOT(sliderMoved( int )) ); connect(m_widget->mute, TQ_SIGNAL(toggled(bool)), Codeine::engine(), TQ_SLOT(setMuted(bool)));
connect( m_widget->slider, SIGNAL(sliderMoved( int )), Codeine::engine(), SLOT(setStreamParameter( int )) ); connect(m_widget->mute, TQ_SIGNAL(toggled(bool)), TQ_SLOT(setMuted(bool)));
connect( m_widget->slider, SIGNAL(sliderReleased()), SLOT(sliderReleased()) ); connect(m_widget->slider, TQ_SIGNAL(valueChanged(int)), Codeine::engine(), TQ_SLOT(setStreamParameter(int)));
connect(m_widget->slider, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(sliderMoved(int)));
} }
int int
@ -69,21 +112,32 @@ VolumeAction::plug( TQWidget *bar, int index )
void void
VolumeAction::toggled( bool const b ) VolumeAction::toggled( bool const b )
{ {
DEBUG_BLOCK
m_widget->raise(); m_widget->raise();
m_widget->setShown( b ); m_widget->setShown( b );
} }
void void
VolumeAction::sliderMoved( int v ) VolumeAction::sliderMoved(int v)
{ {
v = 100 - v; //TQt sliders are wrong way round when vertical // TQt sliders are wrong way round when vertical
v = 100 - v;
auto vol = TQString("%1%").arg(v);
m_widget->label->setText(vol);
setToolTip(i18n("Volume %1").arg(vol));
}
TQString const t = TQString::number( v ) + '%'; void
VolumeAction::setMuted(bool mute)
{
m_widget->setMuted(mute);
}
setToolTip( i18n( "Volume: %1" ).arg( t ) ); void
m_widget->label->setText( t ); VolumeAction::setVolume(int volume)
{
// TQt sliders are the wrong way round when vertical.
m_widget->slider->setValue(100 - volume);
} }
bool bool
@ -94,8 +148,8 @@ VolumeAction::eventFilter( TQObject *o, TQEvent *e )
case TQEvent::Resize: { case TQEvent::Resize: {
TQWidget const * const &a = m_anchor; TQWidget const * const &a = m_anchor;
m_widget->move( a->mapTo( m_widget->parentWidget(), TQPoint( 0, a->height() ) ) ); m_widget->resize( m_widget->requiredWidth, m_widget->sizeHint().height() );
m_widget->resize( a->width(), m_widget->sizeHint().height() ); m_widget->move( a->mapTo( m_widget->parentWidget(), TQPoint( a->width() - m_widget->width(), a->height() ) ) );
return false; return false;
} }

@ -8,7 +8,7 @@
class VolumeAction : public TDEToggleAction class VolumeAction : public TDEToggleAction
{ {
Q_OBJECT TQ_OBJECT
TQWidget *m_anchor; TQWidget *m_anchor;
class VolumeSlider *m_widget; class VolumeSlider *m_widget;
@ -17,10 +17,14 @@ class VolumeAction : public TDEToggleAction
virtual int plug( TQWidget*, int ); virtual int plug( TQWidget*, int );
public slots:
void setMuted(bool mute);
// Update Slider and Label to \a volume
void setVolume(int volume);
private slots: private slots:
void toggled( bool ); void toggled( bool );
void sliderMoved( int ); void sliderMoved(int);
void sliderReleased() { setChecked( false ); toggled( false ); }
public: public:
VolumeAction( TDEToolBar *anchor, TDEActionCollection *ac ); VolumeAction( TDEToolBar *anchor, TDEActionCollection *ac );

@ -24,7 +24,7 @@
TQString i18n(const char *text); TQString i18n(const char *text);
KDialogBase *XineConfigDialog::s_instance = 0; KDialogBase *XineConfigDialog::s_instance = nullptr;
namespace Codeine namespace Codeine
@ -38,22 +38,6 @@ namespace Codeine
} }
} }
class TabWidget : public TQTabWidget
{
public:
TabWidget( TQWidget *parent ) : TQTabWidget( parent ) {}
virtual TQSize sizeHint() const
{
// TQt gives a stupid default sizeHint for this widget
return TQSize(
reinterpret_cast<TQWidget*>(tabBar())->sizeHint().width() + 5,
TQTabWidget::sizeHint().height() );
}
};
///@class XineConfigDialog ///@class XineConfigDialog
XineConfigDialog::XineConfigDialog( xine_t *xine, TQWidget *parent ) XineConfigDialog::XineConfigDialog( xine_t *xine, TQWidget *parent )
@ -68,32 +52,26 @@ XineConfigDialog::XineConfigDialog( xine_t *xine, TQWidget *parent )
DEBUG_BLOCK DEBUG_BLOCK
s_instance = this; s_instance = this;
const int METRIC = fontMetrics().width( 'x' );
const int METRIC_3B2 = (3*METRIC)/2;
TQVBox *box = new TQVBox( this ); TQWidget *page = new TQWidget(this);
box->setSpacing( METRIC ); setMainWidget(page);
setMainWidget( box ); TQVBoxLayout *topLayout = new TQVBoxLayout(page, 0, spacingHint());
{ {
TQHBox *hbox = new TQHBox( box ); TQHBoxLayout *infoLayout = new TQHBoxLayout(topLayout, spacingHint());
hbox->setSpacing( METRIC_3B2 ); TQPixmap info = tdeApp->iconLoader()->loadIcon("messagebox_info", TDEIcon::NoGroup, TDEIcon::SizeMedium, TDEIcon::DefaultState, nullptr, true);
hbox->setMargin( METRIC_3B2 ); TQLabel *label = new TQLabel(page);
TQPixmap info = kapp->iconLoader()->loadIcon( "messagebox_info", TDEIcon::NoGroup, TDEIcon::SizeMedium, TDEIcon::DefaultState, 0, true ); label->setPixmap(info);
TQLabel *label = new TQLabel( hbox ); label->setSizePolicy(TQSizePolicy::Maximum, TQSizePolicy::Maximum);
label->setPixmap( info ); infoLayout->addWidget(label);
label->setSizePolicy( TQSizePolicy::Maximum, TQSizePolicy::Maximum ); label = new TQLabel(i18n(
label = new TQLabel( i18n( "Xine's defaults are usually sensible and should not require modification. "
"xine's defaults are usually sensible and should not require modification. " "However, full configurability is provided for your pleasure ;-)"), page);
"However, full configurability is provided for your pleasure ;-)." ), hbox ); label->setAlignment(TQLabel::WordBreak | TQLabel::AlignVCenter);
label->setAlignment( TQLabel::WordBreak | TQLabel::AlignVCenter ); infoLayout->addWidget(label);
} }
//FIXME after many hours I have discovered that this TQTabWidget *tabs = new TQTabWidget(page);
// widget somehow sets the minSize of this widget to 0,0
// whenever you resize the widget. WTF?
TabWidget *tabs = new TabWidget( box );
class XineConfigEntryIterator { class XineConfigEntryIterator {
xine_t *m_xine; xine_t *m_xine;
@ -102,56 +80,54 @@ XineConfigDialog::XineConfigDialog( xine_t *xine, TQWidget *parent )
public: public:
XineConfigEntryIterator( xine_t *xine ) : m_xine( xine ) { m_valid = xine_config_get_first_entry( m_xine, &m_entry ); } XineConfigEntryIterator( xine_t *xine ) : m_xine( xine ) { m_valid = xine_config_get_first_entry( m_xine, &m_entry ); }
inline XineConfigEntryIterator &operator++() { m_valid = xine_config_get_next_entry( m_xine, &m_entry ); return *this; } inline XineConfigEntryIterator &operator++() { m_valid = xine_config_get_next_entry( m_xine, &m_entry ); return *this; }
inline xine_cfg_entry_t *operator*() { return m_valid ? &m_entry : 0; } inline xine_cfg_entry_t *operator*() { return m_valid ? &m_entry : nullptr; }
}; };
TQGridLayout *grid = nullptr;
TQString currentPageName;
TQScrollView *view = nullptr;
TQWidget *scrollWidget = nullptr;
TQGridLayout *grid = 0; for (XineConfigEntryIterator it(m_xine); *it; ++it)
TQString currentPage;
TQScrollView *view = 0;
parent = 0;
for( XineConfigEntryIterator it( m_xine ); *it; ++it )
{ {
const TQString pageName = TQString::fromUtf8( (*it)->key ).section( '.', 0, 0 ); const TQString pageName = TQString::fromUtf8((*it)->key).section('.', 0, 0);
if( (TQStringList() << "ui" << "effects" << "subtitles").contains( pageName ) ) if ((TQStringList() << "ui" << "effects" << "subtitles").contains(pageName)) {
continue; continue;
}
if( pageName != currentPage ) { if (pageName != currentPageName) {
if( view ) currentPageName = pageName;
//NOTE won't be executed for last tab
view->viewport()->setMinimumWidth( grid->sizeHint().width() ); // seems necessary TQString tabTitle = pageName;
tabTitle[0] = tabTitle[0].upper();
TQString pageTitle = pageName;
pageTitle[0] = pageTitle[0].upper(); view = new TQScrollView(page);
view->setHScrollBarMode(TQScrollView::ScrollBarMode::AlwaysOff);
tabs->addTab( view = new TQScrollView, pageTitle ); // TODO: It would be nice to leave VScrollBarMode on Auto, but
view->setResizePolicy( TQScrollView::AutoOneFit ); // there seems to be an issue when calculating the layout size.
view->setHScrollBarMode( TQScrollView::AlwaysOff ); // https://mirror.git.trinitydesktop.org/gitea/TDE/codeine/pulls/18
view->setFrameShape( TQFrame::NoFrame ); view->setVScrollBarMode(TQScrollView::ScrollBarMode::AlwaysOn);
view->addChild( parent = new TQWidget( view->viewport() ) ); view->setResizePolicy(TQScrollView::AutoOneFit);
view->setFrameShape(TQFrame::NoFrame);
TQBoxLayout *layout = new TQVBoxLayout( parent, /*margin*/METRIC_3B2, /*spacing*/0 ); tabs->addTab(view, tabTitle);
parent = new TQFrame( parent ); scrollWidget = new TQWidget(view->viewport());
static_cast<TQFrame*>(parent)->setFrameStyle( TQFrame::Panel | TQFrame::Raised ); view->addChild(scrollWidget);
static_cast<TQFrame*>(parent)->setLineWidth( 2 );
grid = new TQGridLayout( parent, /*rows*/0, /*cols*/2, /*margin*/20, /*spacing*/int(METRIC*2.5) ); grid = new TQGridLayout(scrollWidget, 0, 2, marginHint(), spacingHint());
grid->setColStretch( 0, 3 ); grid->setColStretch(0, 3);
grid->setColStretch( 1, 2 ); grid->setColStretch(1, 2);
grid->setAlignment(TQt::AlignTop | TQt::AlignAuto);
layout->addWidget( parent, 0 );
layout->addStretch( 1 );
currentPage = pageName;
} }
m_entrys.append( new XineConfigEntry( parent, grid, *it ) ); m_entrys.append(new XineConfigEntry(scrollWidget, grid, *it));
} }
//finishing touches // finishing touches
m_entrys.setAutoDelete( true ); m_entrys.setAutoDelete(true);
topLayout->addWidget(tabs, 1);
enableButton( Ok, false ); enableButton( Ok, false );
enableButton( User1, false ); enableButton( User1, false );
@ -171,7 +147,7 @@ XineConfigDialog::slotHelp()
void void
XineConfigDialog::slotUser1() XineConfigDialog::slotUser1()
{ {
for( TQPtrListIterator<XineConfigEntry> it( m_entrys ); *it != 0; ++it ) for (TQPtrListIterator<XineConfigEntry> it(m_entrys); *it != nullptr; ++it)
(*it)->reset(); (*it)->reset();
slotHelp(); slotHelp();
@ -180,8 +156,8 @@ XineConfigDialog::slotUser1()
bool bool
XineConfigDialog::isUnsavedSettings() const XineConfigDialog::isUnsavedSettings() const
{ {
for( TQPtrListIterator<XineConfigEntry> it( m_entrys ); *it != 0; ++it ) for (TQPtrListIterator<XineConfigEntry> it(m_entrys); *it != nullptr; ++it)
if( (*it)->isChanged() ) if ((*it)->isChanged())
return true; return true;
return false; return false;
@ -202,13 +178,13 @@ XineConfigDialog::saveSettings()
///@class XineConfigEntry ///@class XineConfigEntry
XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg_entry_t *entry ) XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg_entry_t *entry )
: m_widget( 0 ) : m_widget( nullptr )
, m_key( entry->key ) , m_key( entry->key )
, m_string( entry->str_value ) , m_string( entry->str_value )
, m_number( entry->num_value ) , m_number( entry->num_value )
{ {
TQWidget *&w = m_widget; TQWidget *&w = m_widget;
const char *signal = 0; const char *signal = nullptr;
const int row = grid->numRows(); const int row = grid->numRows();
TQString description_text = TQString::fromUtf8( entry->description ); TQString description_text = TQString::fromUtf8( entry->description );
@ -218,7 +194,7 @@ XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg
{ {
case XINE_CONFIG_TYPE_STRING: { case XINE_CONFIG_TYPE_STRING: {
w = new KLineEdit( m_string, parent ); w = new KLineEdit( m_string, parent );
signal = SIGNAL(textChanged( const TQString& )); signal = TQ_SIGNAL(textChanged( const TQString& ));
break; break;
} }
case XINE_CONFIG_TYPE_ENUM: { case XINE_CONFIG_TYPE_ENUM: {
@ -226,7 +202,7 @@ XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg
for( int i = 0; entry->enum_values[i]; ++i ) for( int i = 0; entry->enum_values[i]; ++i )
((KComboBox*)w)->insertItem( TQString::fromUtf8( entry->enum_values[i] ) ); ((KComboBox*)w)->insertItem( TQString::fromUtf8( entry->enum_values[i] ) );
((KComboBox*)w)->setCurrentItem( m_number ); ((KComboBox*)w)->setCurrentItem( m_number );
signal = SIGNAL(activated( int )); signal = TQ_SIGNAL(activated( int ));
break; break;
} }
case XINE_CONFIG_TYPE_RANGE: case XINE_CONFIG_TYPE_RANGE:
@ -236,14 +212,14 @@ XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg
TQMAX( m_number, entry->range_max ), // are both 0 even though this is bullshit TQMAX( m_number, entry->range_max ), // are both 0 even though this is bullshit
1, parent ); 1, parent );
((TQSpinBox*)w)->setValue( m_number ); ((TQSpinBox*)w)->setValue( m_number );
signal = SIGNAL(valueChanged( int )); signal = TQ_SIGNAL(valueChanged( int ));
break; break;
} }
case XINE_CONFIG_TYPE_BOOL: { case XINE_CONFIG_TYPE_BOOL: {
w = new TQCheckBox( description_text, parent ); w = new TQCheckBox( description_text, parent );
((TQCheckBox*)w)->setChecked( m_number ); ((TQCheckBox*)w)->setChecked( m_number );
connect( w, SIGNAL(toggled( bool )), XineConfigDialog::instance(), SLOT(slotHelp()) ); connect( w, TQ_SIGNAL(toggled( bool )), XineConfigDialog::instance(), TQ_SLOT(slotHelp()) );
TQToolTip::add( w, "<qt>" + TQString::fromUtf8( entry->help ) ); TQToolTip::add( w, "<qt>" + TQString::fromUtf8( entry->help ) );
grid->addMultiCellWidget( w, row, row, 0, 1 ); grid->addMultiCellWidget( w, row, row, 0, 1 );
return; //no need for a description label return; //no need for a description label
@ -252,7 +228,7 @@ XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg
; ;
} }
connect( w, signal, XineConfigDialog::instance(), SLOT(slotHelp()) ); connect( w, signal, XineConfigDialog::instance(), TQ_SLOT(slotHelp()) );
TQLabel *description = new TQLabel( description_text + ':', parent ); TQLabel *description = new TQLabel( description_text + ':', parent );
description->setAlignment( TQLabel::WordBreak | TQLabel::AlignVCenter ); description->setAlignment( TQLabel::WordBreak | TQLabel::AlignVCenter );
@ -261,7 +237,7 @@ XineConfigEntry::XineConfigEntry( TQWidget *parent, TQGridLayout *grid, xine_cfg
TQToolTip::add( w, tip ); TQToolTip::add( w, tip );
TQToolTip::add( description, tip ); TQToolTip::add( description, tip );
// grid->addWidget( description, row, 0, TQt::AlignVCenter ); grid->addWidget( description, row, 0, TQt::AlignVCenter );
grid->addWidget( w, row, 1, TQt::AlignTop ); grid->addWidget( w, row, 1, TQt::AlignTop );
} }

@ -25,18 +25,20 @@
namespace Codeine { namespace Codeine {
VideoWindow *VideoWindow::s_instance = 0; VideoWindow *VideoWindow::s_instance = nullptr;
bool VideoWindow::s_logarithmicVolume = false;
VideoWindow::VideoWindow( TQWidget *parent ) VideoWindow::VideoWindow( TQWidget *parent )
: TQWidget( parent, "VideoWindow" ) : TQWidget( parent, "VideoWindow" )
, m_osd( 0 ) , m_osd( nullptr )
, m_stream( 0 ) , m_stream( nullptr )
, m_eventQueue( 0 ) , m_eventQueue( nullptr )
, m_videoPort( 0 ) , m_videoPort( nullptr )
, m_audioPort( 0 ) , m_audioPort( nullptr )
, m_scope( 0 ) , m_post( nullptr )
, m_xine( 0 ) , m_xine( nullptr )
, m_scope( Analyzer::SCOPE_SIZE * 2 ) // Multiply by two to account for interleaved PCM.
, m_current_vpts( 0 ) , m_current_vpts( 0 )
{ {
DEBUG_BLOCK DEBUG_BLOCK
@ -50,9 +52,12 @@ VideoWindow::VideoWindow( TQWidget *parent )
setPaletteBackgroundColor( TQt::black ); setPaletteBackgroundColor( TQt::black );
setFocusPolicy( ClickFocus ); setFocusPolicy( ClickFocus );
//TODO sucks // Detect xine version, this is used for volume adjustment.
//TODO namespace this? // Xine versions prior to 1.2.13 use linear volume, so the engine uses logarithmic volume.
myList->next = myList; //init the buffer list // Xine versions starting from 1.2.13 use logarithmic volume, so the engine uses linear volume.
int xinemajor = 0, xineminor = 0, xinemaint = 0;
xine_get_version(&xinemajor, &xineminor, &xinemaint);
s_logarithmicVolume = (xinemajor * 1000000 + xineminor * 1000 + xinemaint < 1002013);
} }
VideoWindow::~VideoWindow() VideoWindow::~VideoWindow()
@ -65,7 +70,12 @@ VideoWindow::~VideoWindow()
if( m_stream && xine_get_status( m_stream ) == XINE_STATUS_PLAY ) { if( m_stream && xine_get_status( m_stream ) == XINE_STATUS_PLAY ) {
int cum = 0; int cum = 0;
for( int v = 99; v >= 0; v-- ) { for( int v = 99; v >= 0; v-- ) {
xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, v ); int vol = v;
if (s_logarithmicVolume)
{
vol = makeVolumeLogarithmic(vol);
}
xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, vol );
int sleep = int(32000 * (-std::log10( double(v + 1) ) + 2)); int sleep = int(32000 * (-std::log10( double(v + 1) ) + 2));
::usleep( sleep ); ::usleep( sleep );
@ -88,7 +98,7 @@ VideoWindow::~VideoWindow()
if( m_stream ) xine_dispose( m_stream ); if( m_stream ) xine_dispose( m_stream );
if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort ); if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort );
if( m_videoPort ) xine_close_video_driver( m_xine, m_videoPort ); if( m_videoPort ) xine_close_video_driver( m_xine, m_videoPort );
if( m_scope ) xine_post_dispose( m_xine, m_scope ); if( m_post ) xine_post_dispose( m_xine, m_post );
if( m_xine ) xine_exit( m_xine ); if( m_xine ) xine_exit( m_xine );
cleanUpVideo(); cleanUpVideo();
@ -106,7 +116,7 @@ VideoWindow::init()
if( !m_xine ) if( !m_xine )
return false; return false;
xine_engine_set_param( m_xine, XINE_ENGINE_PARAM_VERBOSITY, 99 ); xine_engine_set_param(m_xine, XINE_ENGINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG);
debug() << "xine_config_load()\n"; debug() << "xine_config_load()\n";
xine_config_load( m_xine, TQFile::encodeName( TQDir::homeDirPath() + "/.xine/config" ) ); xine_config_load( m_xine, TQFile::encodeName( TQDir::homeDirPath() + "/.xine/config" ) );
@ -123,7 +133,7 @@ VideoWindow::init()
m_videoPort = xine_open_video_driver( m_xine, "auto", XINE_VISUAL_TYPE_X11, videoWindow()->x11Visual() ); m_videoPort = xine_open_video_driver( m_xine, "auto", XINE_VISUAL_TYPE_X11, videoWindow()->x11Visual() );
debug() << "xine_open_audio_driver()\n"; debug() << "xine_open_audio_driver()\n";
m_audioPort = xine_open_audio_driver( m_xine, "auto", NULL ); m_audioPort = xine_open_audio_driver( m_xine, "auto", nullptr );
debug() << "xine_stream_new()\n"; debug() << "xine_stream_new()\n";
m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort ); m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort );
@ -148,9 +158,9 @@ VideoWindow::init()
debug() << "scope_plugin_new()\n"; debug() << "scope_plugin_new()\n";
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
m_scope = xine_post_init( m_xine, "codeine-scope", 1, &m_audioPort, NULL ); m_post = xine_post_init( m_xine, "codeine-scope", 1, &m_audioPort, nullptr );
#else #else
m_scope = scope_plugin_new( m_xine, m_audioPort ); m_post = scope_plugin_new( m_xine, m_audioPort );
//FIXME this one seems to make seeking unstable for Codeine, perhaps //FIXME this one seems to make seeking unstable for Codeine, perhaps
xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); //less buffering, faster seeking.. xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); //less buffering, faster seeking..
@ -255,6 +265,7 @@ VideoWindow::load( const KURL &url )
setParameter( XINE_PARAM_SPU_CHANNEL, -1 ); setParameter( XINE_PARAM_SPU_CHANNEL, -1 );
setParameter( XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -1 ); setParameter( XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -1 );
setParameter( XINE_PARAM_VO_ASPECT_RATIO, 0 ); setParameter( XINE_PARAM_VO_ASPECT_RATIO, 0 );
// 100 is the same for both linear and logarithmic volume control
setParameter( XINE_PARAM_AUDIO_AMP_LEVEL, 100 ); setParameter( XINE_PARAM_AUDIO_AMP_LEVEL, 100 );
#undef setParameter #undef setParameter
@ -265,11 +276,11 @@ VideoWindow::load( const KURL &url )
// ensure old buffers are deleted // ensure old buffers are deleted
// FIXME leaves one erroneous buffer // FIXME leaves one erroneous buffer
timerEvent( 0 ); timerEvent( nullptr );
if( m_scope ) { if( m_post ) {
xine_post_out_t *source = xine_get_audio_source( m_stream ); xine_post_out_t *source = xine_get_audio_source( m_stream );
xine_post_in_t *target = (xine_post_in_t*)xine_post_input( m_scope, const_cast<char*>("audio in") ); xine_post_in_t *target = (xine_post_in_t*)xine_post_input( m_post, const_cast<char*>("audio in") );
xine_post_wire( source, target ); xine_post_wire( source, target );
} }
@ -359,6 +370,8 @@ VideoWindow::stop()
{ {
xine_stop( m_stream ); xine_stop( m_stream );
std::fill(m_scope.begin(), m_scope.end(), 0);
announceStateChange(); announceStateChange();
} }
@ -442,11 +455,29 @@ VideoWindow::posTimeLength( PosTimeLength type ) const
return 0; //--warning return 0; //--warning
} }
bool
VideoWindow::isMuted() const
{
return xine_get_param(m_stream, XINE_PARAM_AUDIO_AMP_MUTE);
}
uint uint
VideoWindow::volume() const VideoWindow::volume() const
{ {
//TODO I don't like the design int vol = xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL );
return xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL ); if (s_logarithmicVolume)
{
vol = 100 - 100.0 * (pow(10, (100.0 - vol) / 100.0) - 1) / 9.0;
}
if (vol < 0)
{
vol = 0;
}
if (vol > 100)
{
vol = 100;
}
return (uint)vol;
} }
void void
@ -492,12 +523,6 @@ VideoWindow::seek( uint pos )
return; return;
} }
//TODO depend on a version that CAN seek in flacs!
if( m_url.path().endsWith( ".flac", false ) ) {
emit statusMessage( i18n("xine cannot currently seek in flac media") );
return;
}
//better feedback //better feedback
//NOTE doesn't work! I can't tell why.. //NOTE doesn't work! I can't tell why..
Slider::instance()->TQSlider::setValue( pos ); Slider::instance()->TQSlider::setValue( pos );
@ -532,6 +557,13 @@ VideoWindow::seek( uint pos )
xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_MUTE, 0 ); xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_MUTE, 0 );
} }
int
VideoWindow::makeVolumeLogarithmic(int volume)
{
// We're using a logarithmic function to make the volume ramp more natural.
return static_cast<uint>( 100 - 100.0 * std::log10( ( 100 - volume ) * 0.09 + 1.0 ) );
}
void void
VideoWindow::setStreamParameter( int value ) VideoWindow::setStreamParameter( int value )
{ {
@ -546,39 +578,61 @@ VideoWindow::setStreamParameter( int value )
parameter = XINE_PARAM_VO_CONTRAST; parameter = XINE_PARAM_VO_CONTRAST;
else if( sender == "brightness" ) else if( sender == "brightness" )
parameter = XINE_PARAM_VO_BRIGHTNESS; parameter = XINE_PARAM_VO_BRIGHTNESS;
else if( sender == "subtitle_channels_menu" ) else if( sender == "subtitle_channels_select" )
parameter = XINE_PARAM_SPU_CHANNEL, parameter = XINE_PARAM_SPU_CHANNEL,
value -= 2; value -= 2;
else if( sender == "audio_channels_menu" ) else if( sender == "audio_channels_select" )
parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL, parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
value -= 2; value -= 2;
else if( sender == "aspect_ratio_menu" ) else if( sender == "aspect_ratio_select" )
parameter = XINE_PARAM_VO_ASPECT_RATIO; parameter = XINE_PARAM_VO_ASPECT_RATIO;
else if( sender == "volume" ) else if( sender == "volume" )
{
parameter = XINE_PARAM_AUDIO_AMP_LEVEL; parameter = XINE_PARAM_AUDIO_AMP_LEVEL;
value = 100 - value; // TQt sliders are the wrong way round when vertical
if (s_logarithmicVolume)
{
value = makeVolumeLogarithmic(value);
}
}
else else
return; return;
xine_set_param( m_stream, parameter, value ); xine_set_param( m_stream, parameter, value );
} }
void
VideoWindow::setMuted(bool mute)
{
xine_set_param(m_stream, XINE_PARAM_AUDIO_AMP_MUTE, mute);
}
const Engine::Scope& const Engine::Scope&
VideoWindow::scope() VideoWindow::scope()
{ {
using Analyzer::SCOPE_SIZE; using Analyzer::SCOPE_SIZE;
static Engine::Scope scope( SCOPE_SIZE ); if (!m_post || !m_stream || xine_get_status(m_stream) != XINE_STATUS_PLAY)
{
return m_scope;
}
MyNode *const myList = scope_plugin_list(m_post);
const int64_t pts_per_smpls = scope_plugin_pts_per_smpls(m_post);
const int channels = scope_plugin_channels(m_post);
int scopeIdx = 0;
if( xine_get_status( m_stream ) != XINE_STATUS_PLAY ) if (channels > 2)
return scope; {
return m_scope;
}
//prune the buffer list and update the m_current_vpts timestamp //prune the buffer list and update the m_current_vpts timestamp
timerEvent( 0 ); timerEvent( nullptr );
const int64_t pts_per_smpls = 0; //scope_plugin_pts_per_smpls( m_scope ); for (int n, frame = 0; frame < SCOPE_SIZE; /* no-op */)
for( int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_CHANNELS ), frame = 0; frame < SCOPE_SIZE; )
{ {
MyNode *best_node = 0; MyNode *best_node = nullptr;
for( MyNode *node = myList->next; node != myList; node = node->next ) for( MyNode *node = myList->next; node != myList; node = node->next )
if( node->vpts <= m_current_vpts && (!best_node || node->vpts > best_node->vpts) ) if( node->vpts <= m_current_vpts && (!best_node || node->vpts > best_node->vpts) )
@ -597,10 +651,10 @@ VideoWindow::scope()
data16 = best_node->mem; data16 = best_node->mem;
data16 += diff; data16 += diff;
diff += diff % channels; //important correction to ensure we don't overflow the buffer diff += diff % channels; // important correction to ensure we don't overflow the buffer.
diff /= channels; diff /= channels; // use units of frames, not samples.
int // calculate the number of available samples in this buffer.
n = best_node->num_frames; n = best_node->num_frames;
n -= diff; n -= diff;
n += frame; //clipping for # of frames we need n += frame; //clipping for # of frames we need
@ -610,33 +664,52 @@ VideoWindow::scope()
for( int a, c; frame < n; ++frame, data16 += channels ) { for( int a, c; frame < n; ++frame, data16 += channels ) {
for( a = c = 0; c < channels; ++c ) for( a = c = 0; c < channels; ++c )
a += data16[c]; {
// now we give interleaved PCM to the scope.
a /= channels; m_scope[scopeIdx++] = data16[c];
scope[frame] = a; if (channels == 1)
{
// Duplicate mono samples.
m_scope[scopeIdx++] = data16[c];
}
}
} }
m_current_vpts = best_node->vpts_end; m_current_vpts = best_node->vpts_end;
m_current_vpts++; //FIXME needs to be done for some reason, or you get situations where it uses same buffer again and again m_current_vpts++; //FIXME needs to be done for some reason, or you get situations where it uses same buffer again and again
} }
return scope; return m_scope;
} }
void void
VideoWindow::timerEvent( TQTimerEvent* ) VideoWindow::timerEvent( TQTimerEvent* )
{ {
if (!m_stream)
{
return;
}
/// here we prune the buffer list regularly /// here we prune the buffer list regularly
MyNode * const first_node = myList->next; MyNode *myList = scope_plugin_list(m_post);
MyNode const * const list_end = myList;
if (!myList)
{
return;
}
// We operate on a subset of the list for thread-safety.
MyNode *const firstNode = myList->next;
const MyNode *const listEnd = myList;
// If we're not playing or paused, empty the list.
m_current_vpts = (xine_get_status( m_stream ) == XINE_STATUS_PLAY) m_current_vpts = (xine_get_status( m_stream ) == XINE_STATUS_PLAY)
? xine_get_current_vpts( m_stream ) ? xine_get_current_vpts( m_stream )
: std::numeric_limits<int64_t>::max(); : std::numeric_limits<int64_t>::max();
for( MyNode *prev = first_node, *node = first_node->next; node != list_end; node = node->next ) for( MyNode *prev = firstNode, *node = firstNode->next; node != listEnd; node = node->next )
{ {
// we never delete first_node // we never delete firstNode
// this maintains thread-safety // this maintains thread-safety
if( node->vpts_end < m_current_vpts ) { if( node->vpts_end < m_current_vpts ) {
prev->next = node->next; prev->next = node->next;
@ -669,19 +742,19 @@ VideoWindow::customEvent( TQCustomEvent *e )
char s[128]; //apparently sufficient char s[128]; //apparently sufficient
{ {
TQStringList languages( "subtitle_channels_menu" ); TQStringList languages;
int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL ); int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL );
for( int j = 0; j < channels; j++ ) for( int j = 0; j < channels; j++ )
languages += xine_get_spu_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 ); languages += xine_get_spu_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 );
emit channelsChanged( languages ); emit subtitleChannelsChanged(languages);
} }
{ {
TQStringList languages( "audio_channels_menu" ); TQStringList languages;
int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL ); int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL );
for( int j = 0; j < channels; j++ ) for( int j = 0; j < channels; j++ )
languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 ); languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 );
emit channelsChanged( languages ); emit audioChannelsChanged(languages);
} }
break; break;
} }
@ -722,7 +795,7 @@ VideoWindow::xineEventListener( void *p, const xine_event_t* xineEvent )
//FIXME this is not the right way, it will have bugs //FIXME this is not the right way, it will have bugs
debug() << "XINE_EVENT_MRL_REFERENCE\n"; debug() << "XINE_EVENT_MRL_REFERENCE\n";
engine->m_url = TQString::fromUtf8( ((xine_mrl_reference_data_ext_t*)xineEvent->data)->mrl ); engine->m_url = TQString::fromUtf8( ((xine_mrl_reference_data_ext_t*)xineEvent->data)->mrl );
TQTimer::singleShot( 0, engine, SLOT(play()) ); TQTimer::singleShot( 0, engine, TQ_SLOT(play()) );
break; break;
} }
case XINE_EVENT_DROPPED_FRAMES: debug() << "XINE_EVENT_DROPPED_FRAMES\n"; break; case XINE_EVENT_DROPPED_FRAMES: debug() << "XINE_EVENT_DROPPED_FRAMES\n"; break;
@ -840,7 +913,7 @@ VideoWindow::toggleDVDMenu()
{ {
xine_event_t e; xine_event_t e;
e.type = XINE_EVENT_INPUT_MENU1; e.type = XINE_EVENT_INPUT_MENU1;
e.data = NULL; e.data = nullptr;
e.data_length = 0; e.data_length = 0;
xine_event_send( m_stream, &e ); xine_event_send( m_stream, &e );
@ -862,13 +935,37 @@ VideoWindow::fileFilter() const
{ {
char *supportedExtensions = xine_get_file_extensions( m_xine ); char *supportedExtensions = xine_get_file_extensions( m_xine );
TQString filter( "*." ); TQString filter("*.");
filter.append( supportedExtensions ); filter.append(supportedExtensions);
filter.remove( "txt" );
filter.remove( "png" ); // Remove protocols
filter.replace( ' ', " *." ); filter.remove(" dvb://");
filter.remove(" dvbc://");
std::free( supportedExtensions ); filter.remove(" dvbs://");
filter.remove(" dvbt://");
filter.remove(" vcd:/");
filter.remove(" vdr:/");
filter.remove(" netvdr:/");
filter.remove(" dvd:/");
filter.remove(" pvr:/");
filter.remove(" slave://");
filter.remove(" cdda:/");
// Remove image files
filter.remove(" bmp");
filter.remove(" gif");
filter.remove(" jpg");
filter.remove(" jpeg");
filter.remove(" png");
// Remove misc. files
filter.remove(" txt");
// Remove spaces (prevent multiple *.)
filter.replace(" ", " ");
filter.replace(' ', " *.");
std::free(supportedExtensions);
return filter; return filter;
} }

@ -34,11 +34,12 @@ namespace Codeine
*/ */
class VideoWindow : public TQWidget class VideoWindow : public TQWidget
{ {
Q_OBJECT TQ_OBJECT
enum PosTimeLength { Pos, Time, Length }; enum PosTimeLength { Pos, Time, Length };
static VideoWindow *s_instance; static VideoWindow *s_instance;
static bool s_logarithmicVolume;
VideoWindow( const VideoWindow& ); //disable VideoWindow( const VideoWindow& ); //disable
VideoWindow &operator=( const VideoWindow& ); //disable VideoWindow &operator=( const VideoWindow& ); //disable
@ -61,6 +62,7 @@ namespace Codeine
uint time() const { return posTimeLength( Time ); } uint time() const { return posTimeLength( Time ); }
uint length() const { return posTimeLength( Length ); } uint length() const { return posTimeLength( Length ); }
bool isMuted() const;
uint volume() const; uint volume() const;
const Engine::Scope &scope(); const Engine::Scope &scope();
@ -77,12 +79,14 @@ namespace Codeine
///special slot, see implementation to facilitate understanding ///special slot, see implementation to facilitate understanding
void setStreamParameter( int ); void setStreamParameter( int );
void setMuted(bool);
signals: signals:
void stateChanged( Engine::State ); void stateChanged( Engine::State );
void statusMessage( const TQString& ); void statusMessage( const TQString& );
void titleChanged( const TQString& ); void titleChanged( const TQString& );
void channelsChanged( const TQStringList& ); void audioChannelsChanged( const TQStringList &);
void subtitleChannelsChanged( const TQStringList &);
private: private:
static void xineEventListener( void*, const xine_event_t* ); static void xineEventListener( void*, const xine_event_t* );
@ -102,9 +106,10 @@ namespace Codeine
xine_event_queue_t *m_eventQueue; xine_event_queue_t *m_eventQueue;
xine_video_port_t *m_videoPort; xine_video_port_t *m_videoPort;
xine_audio_port_t *m_audioPort; xine_audio_port_t *m_audioPort;
xine_post_t *m_scope; xine_post_t *m_post;
xine_t *m_xine; xine_t *m_xine;
Engine::Scope m_scope;
int64_t m_current_vpts; int64_t m_current_vpts;
KURL m_url; KURL m_url;
@ -120,6 +125,7 @@ namespace Codeine
private: private:
static void destSizeCallBack( void*, int, int, double, int*, int*, double* ); static void destSizeCallBack( void*, int, int, double, int*, int*, double* );
static void frameOutputCallBack( void*, int, int, double, int*, int*, int*, int*, double*, int*, int* ); static void frameOutputCallBack( void*, int, int, double, int*, int*, int*, int*, double*, int*, int* );
static int makeVolumeLogarithmic(int volume);
void initVideo(); void initVideo();
void cleanUpVideo(); void cleanUpVideo();
@ -134,8 +140,6 @@ namespace Codeine
void becomePreferredSize(); void becomePreferredSize();
TQImage captureFrame() const; TQImage captureFrame() const;
enum { ExposeEvent = 3000 };
public slots: public slots:
void resetZoom(); void resetZoom();

@ -4,16 +4,38 @@
/* need access to port_ticket */ /* need access to port_ticket */
#define XINE_ENGINE_INTERNAL #define XINE_ENGINE_INTERNAL
#define LOG_MODULE "codine-scope"
#define LOG_LEVEL LOG_LEVEL_DEBUG
// #define LOG
#include "xineScope.h" #include "xineScope.h"
#include <xine/post.h> #include <xine/post.h>
#include <xine/xine_internal.h> #include <xine/xine_internal.h>
typedef struct scope_plugin_s {
post_plugin_t super;
int channels;
int64_t pts_per_smpls;
MyNode *list;
} scope_plugin_t;
static MyNode theList; int scope_plugin_channels(void *post)
static int myChannels = 0; {
static int64_t pts_per_smpls; scope_plugin_t *self = post;
return self->channels;
}
MyNode* const myList = &theList; MyNode *scope_plugin_list(void *post)
{
scope_plugin_t *self = post;
return self->list;
}
int64_t scope_plugin_pts_per_smpls(void *post)
{
scope_plugin_t *self = post;
return self->pts_per_smpls;
}
/************************* /*************************
* post plugin functions * * post plugin functions *
@ -22,7 +44,10 @@ MyNode* const myList = &theList;
static int static int
scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode ) scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode )
{ {
lprintf("scope_port_open()\n");
post_audio_port_t *port = (post_audio_port_t *)port_gen; post_audio_port_t *port = (post_audio_port_t *)port_gen;
scope_plugin_t *self = (scope_plugin_t *)port->post;
_x_post_rewire( (post_plugin_t*)port->post ); _x_post_rewire( (post_plugin_t*)port->post );
_x_post_inc_usage( port ); _x_post_inc_usage( port );
@ -32,14 +57,14 @@ scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bi
port->rate = rate; port->rate = rate;
port->mode = mode; port->mode = mode;
myChannels = _x_ao_mode2channels( mode ); self->channels = _x_ao_mode2channels(mode);
int ret = port->original_port->open( port->original_port, stream, bits, rate, mode ); int ret = port->original_port->open( port->original_port, stream, bits, rate, mode );
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate; self->pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate;
#else #else
pts_per_smpls = stream->metronom->pts_per_smpls; self->pts_per_smpls = stream->metronom->pts_per_smpls;
#endif #endif
return ret; return ret;
} }
@ -47,7 +72,17 @@ scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bi
static void static void
scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream ) scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream )
{ {
lprintf("scope_port_close()\n");
post_audio_port_t *port = (post_audio_port_t *)port_gen; post_audio_port_t *port = (post_audio_port_t *)port_gen;
scope_plugin_t *self = (scope_plugin_t *)port->post;
/* ensure the buffers are deleted during the next VideoWindow::timerEvent */
MyNode *node;
for (node = self->list->next; node != self->list; node = node->next)
{
node->vpts = node->vpts_end - 1;
}
port->stream = NULL; port->stream = NULL;
port->original_port->close( port->original_port, stream ); port->original_port->close( port->original_port, stream );
@ -59,6 +94,7 @@ static void
scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream ) scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream )
{ {
post_audio_port_t *port = (post_audio_port_t *)port_gen; post_audio_port_t *port = (post_audio_port_t *)port_gen;
scope_plugin_t *self = (scope_plugin_t *)port->post;
/* we are too simple to handle 8bit */ /* we are too simple to handle 8bit */
/* what does it mean when stream == NULL? */ /* what does it mean when stream == NULL? */
@ -66,7 +102,7 @@ scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_st
port->original_port->put_buffer( port->original_port, buf, stream ); return; } port->original_port->put_buffer( port->original_port, buf, stream ); return; }
MyNode *new_node; MyNode *new_node;
const int num_samples = buf->num_frames * myChannels; const int num_samples = buf->num_frames * self->channels;
new_node = malloc( sizeof(MyNode) ); new_node = malloc( sizeof(MyNode) );
#ifdef METRONOM_VPTS #ifdef METRONOM_VPTS
@ -80,7 +116,7 @@ scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_st
{ {
int64_t int64_t
K = pts_per_smpls; /*smpls = 1<<16 samples*/ K = self->pts_per_smpls; /*smpls = 1<<16 samples*/
K *= num_samples; K *= num_samples;
K /= (1<<16); K /= (1<<16);
K += new_node->vpts; K += new_node->vpts;
@ -93,14 +129,29 @@ scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_st
/* finally we should append the current buffer to the list /* finally we should append the current buffer to the list
* NOTE this is thread-safe due to the way we handle the list in the GUI thread */ * NOTE this is thread-safe due to the way we handle the list in the GUI thread */
new_node->next = myList->next; new_node->next = self->list->next;
myList->next = new_node; self->list->next = new_node;
} }
static void static void
scope_dispose( post_plugin_t *this ) scope_dispose( post_plugin_t *this )
{ {
free( this ); MyNode *list = ((scope_plugin_t *)this)->list;
MyNode *prev;
MyNode *node = list;
/* Free all elements of the list (a ring buffer) */
do
{
prev = node->next;
free(node->mem);
free(node);
node = prev;
} while(node != list);
free(this);
} }
@ -118,15 +169,15 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
if( audio_target == NULL ) if( audio_target == NULL )
return NULL; return NULL;
post_plugin_t *post_plugin = calloc( 1, sizeof(post_plugin_t) ); scope_plugin_t *scope_plugin = calloc(1, sizeof(scope_plugin_t));
post_plugin_t *post_plugin = (post_plugin_t *)scope_plugin;
{ {
post_plugin_t *this = post_plugin;
post_in_t *input; post_in_t *input;
post_out_t *output; post_out_t *output;
post_audio_port_t *port; post_audio_port_t *port;
_x_post_init( this, 1, 0 ); _x_post_init(post_plugin, 1, 0);
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
@ -138,10 +189,10 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
port->new_port.close = scope_port_close; port->new_port.close = scope_port_close;
port->new_port.put_buffer = scope_port_put_buffer; port->new_port.put_buffer = scope_port_put_buffer;
this->xine_post.audio_input[0] = &port->new_port; post_plugin->xine_post.audio_input[0] = &port->new_port;
this->xine_post.type = PLUGIN_POST; post_plugin->xine_post.type = PLUGIN_POST;
this->dispose = scope_dispose; post_plugin->dispose = scope_dispose;
} }
#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ #if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \
@ -153,6 +204,12 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
post_plugin->xine = xine; post_plugin->xine = xine;
#endif #endif
/* scope_plugin_t init */
scope_plugin->channels = 0;
scope_plugin->pts_per_smpls = 0;
scope_plugin->list = calloc(1, sizeof(MyNode));
scope_plugin->list->next = scope_plugin->list;
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
return post_plugin; return post_plugin;
@ -161,11 +218,6 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
#endif #endif
} }
int64_t scope_plugin_pts_per_smpls( void *post )
{
return pts_per_smpls;
}
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
static void *scope_init_plugin(xine_t *xine, const void *data) static void *scope_init_plugin(xine_t *xine, const void *data)

@ -33,18 +33,23 @@ struct my_node_s
int64_t vpts_end; int64_t vpts_end;
}; };
extern MyNode* const myList;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif
#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ #if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
extern const plugin_info_t scope_plugin_info[]; extern const plugin_info_t scope_plugin_info[];
#else #else
xine_post_t* scope_plugin_new( xine_t*, xine_audio_port_t* ); xine_post_t* scope_plugin_new( xine_t*, xine_audio_port_t* );
#endif #endif
int64_t scope_plugin_pts_per_smpls( void* );
int scope_plugin_channels(void *);
MyNode *scope_plugin_list(void *);
int64_t scope_plugin_pts_per_smpls(void *);
#ifdef __cplusplus
} }
#endif #endif

@ -164,7 +164,7 @@ namespace Debug
Block( const char *label ) Block( const char *label )
: m_label( label ) : m_label( label )
{ {
gettimeofday( &m_start, 0 ); gettimeofday( &m_start, nullptr );
kdDebug() << indent() << "BEGIN: " << label << "\n"; kdDebug() << indent() << "BEGIN: " << label << "\n";
DEBUG_INDENT DEBUG_INDENT
@ -173,7 +173,7 @@ namespace Debug
~Block() ~Block()
{ {
timeval end; timeval end;
gettimeofday( &end, 0 ); gettimeofday( &end, nullptr );
end.tv_sec -= m_start.tv_sec; end.tv_sec -= m_start.tv_sec;
if( end.tv_usec < m_start.tv_usec) { if( end.tv_usec < m_start.tv_usec) {

@ -35,8 +35,8 @@ namespace Codeine
//FIXME this will terminate the host, eg Konqueror //FIXME this will terminate the host, eg Konqueror
Debug::fatal() << "Couldn't init xine!\n"; Debug::fatal() << "Couldn't init xine!\n";
TDEAction *play = new TDEToggleAction( i18n("Play"), "media-playback-start", TQt::Key_Space, videoWindow(), SLOT(togglePlay()), actionCollection(), "play" ); TDEAction *play = new TDEToggleAction( i18n("Play"), "media-playback-start", TQt::Key_Space, videoWindow(), TQ_SLOT(togglePlay()), actionCollection(), "play" );
TDEAction *mute = new TDEToggleAction( i18n("Mute"), "player_mute", TQt::Key_M, videoWindow(), SLOT(toggleMute()), actionCollection(), "mute" ); TDEAction *mute = new TDEToggleAction( i18n("Mute"), "player_mute", TQt::Key_M, videoWindow(), TQ_SLOT(toggleMute()), actionCollection(), "mute" );
TDEToolBar *toolBar = new MouseOverToolBar( widget() ); TDEToolBar *toolBar = new MouseOverToolBar( widget() );
play->plug( toolBar ); play->plug( toolBar );
mute->plug( toolBar ); mute->plug( toolBar );
@ -46,8 +46,8 @@ namespace Codeine
toolBar->addSeparator(); //FIXME ugly toolBar->addSeparator(); //FIXME ugly
TQObject *o = (TQObject*)statusBar(); TQObject *o = (TQObject*)statusBar();
connect( videoWindow(), SIGNAL(statusMessage( const TQString& )), o, SLOT(message( const TQString& )) ); connect( videoWindow(), TQ_SIGNAL(statusMessage( const TQString& )), o, TQ_SLOT(message( const TQString& )) );
connect( videoWindow(), SIGNAL(titleChanged( const TQString& )), o, SLOT(message( const TQString& )) ); //FIXME connect( videoWindow(), TQ_SIGNAL(titleChanged( const TQString& )), o, TQ_SLOT(message( const TQString& )) ); //FIXME
} }
bool bool

@ -18,7 +18,7 @@
namespace Codeine { namespace Codeine {
VideoWindow *VideoWindow::s_instance = 0; VideoWindow *VideoWindow::s_instance = nullptr;
namespace X namespace X
@ -30,12 +30,12 @@ namespace X
VideoWindow::VideoWindow( TQWidget *parent, const char *name ) VideoWindow::VideoWindow( TQWidget *parent, const char *name )
: TQWidget( parent, name ) : TQWidget( parent, name )
, m_osd( 0 ) , m_osd( nullptr )
, m_stream( 0 ) , m_stream( nullptr )
, m_eventQueue( 0 ) , m_eventQueue( nullptr )
, m_videoPort( 0 ) , m_videoPort( nullptr )
, m_audioPort( 0 ) , m_audioPort( nullptr )
, m_xine( 0 ) , m_xine( nullptr )
, m_displayRatio( 1 ) , m_displayRatio( 1 )
{ {
s_instance = this; s_instance = this;
@ -71,7 +71,7 @@ VideoWindow::VideoWindow( TQWidget *parent, const char *name )
XUnlockDisplay( X::d ); XUnlockDisplay( X::d );
connect( &m_timer, SIGNAL(timeout()), SLOT(hideCursor()) ); connect( &m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(hideCursor()) );
} }
VideoWindow::~VideoWindow() VideoWindow::~VideoWindow()

@ -24,7 +24,7 @@ namespace Codeine
{ {
class VideoWindow : public TQWidget class VideoWindow : public TQWidget
{ {
Q_OBJECT TQ_OBJECT
static VideoWindow *s_instance; static VideoWindow *s_instance;
static const uint CURSOR_HIDE_TIMEOUT = 2000; static const uint CURSOR_HIDE_TIMEOUT = 2000;

@ -37,7 +37,7 @@ VideoWindow::init()
m_videoPort = xine_open_video_driver( m_xine, "auto", XINE_VISUAL_TYPE_X11, x11Visual() ); m_videoPort = xine_open_video_driver( m_xine, "auto", XINE_VISUAL_TYPE_X11, x11Visual() );
debug() << "xine_open_audio_driver()\n"; debug() << "xine_open_audio_driver()\n";
m_audioPort = xine_open_audio_driver( m_xine, "auto", NULL ); m_audioPort = xine_open_audio_driver( m_xine, "auto", nullptr );
debug() << "xine_stream_new()\n"; debug() << "xine_stream_new()\n";
m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort ); m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort );

@ -1,13 +1,14 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# This file is put in the public domain. # This file is put in the public domain.
# Eduardo Herrera <edhu21@gmail.com>, 2023. # Eduardo Herrera <edhu21@gmail.com>, 2023.
# Juan M Ayala <linux.zero@yahoo.com>, 2025.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-28 16:45+0200\n" "POT-Creation-Date: 2020-06-28 16:45+0200\n"
"PO-Revision-Date: 2023-03-21 23:14+0000\n" "PO-Revision-Date: 2025-01-20 18:16+0000\n"
"Last-Translator: Eduardo Herrera <edhu21@gmail.com>\n" "Last-Translator: Juan M Ayala <linux.zero@yahoo.com>\n"
"Language-Team: Spanish <https://mirror.git.trinitydesktop.org/weblate/" "Language-Team: Spanish <https://mirror.git.trinitydesktop.org/weblate/"
"projects/applications/codeine-desktop-files/es/>\n" "projects/applications/codeine-desktop-files/es/>\n"
"Language: es\n" "Language: es\n"
@ -15,12 +16,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.16.1\n" "X-Generator: Weblate 4.17\n"
#. Name #. Name
#: codeine.desktop:3 codeine_part.desktop:3 #: codeine.desktop:3 codeine_part.desktop:3
msgid "Codeine" msgid "Codeine"
msgstr "" msgstr "Codeine"
#. GenericName #. GenericName
#: codeine.desktop:5 #: codeine.desktop:5
@ -30,12 +31,13 @@ msgstr "Reproductor multimedia"
#. Comment #. Comment
#: codeine.desktop:7 #: codeine.desktop:7
msgid "Video player for TDE designed to be as simple as possible" msgid "Video player for TDE designed to be as simple as possible"
msgstr "Reproductor de vídeo para TDE diseñado para ser lo más sencillo posible" msgstr ""
"Reproductor de vídeo para TDE diseñado para ser lo más sencillo posible"
#. Comment #. Comment
#: codeine_part.desktop:5 #: codeine_part.desktop:5
msgid "Embeddable Video Player" msgid "Embeddable Video Player"
msgstr "" msgstr "Reproductor de Vídeo Integrable"
#. Name #. Name
#: codeine_play_dvd.desktop:8 #: codeine_play_dvd.desktop:8

@ -0,0 +1,45 @@
# SOME DESCRIPTIVE TITLE.
# This file is put in the public domain.
# Temuri Doghonadze <rkavt@smartprojects.ge>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-28 16:45+0200\n"
"PO-Revision-Date: 2024-11-06 18:11+0000\n"
"Last-Translator: Temuri Doghonadze <rkavt@smartprojects.ge>\n"
"Language-Team: Georgian <https://mirror.git.trinitydesktop.org/weblate/"
"projects/applications/codeine-desktop-files/ka/>\n"
"Language: ka\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. Name
#: codeine.desktop:3 codeine_part.desktop:3
msgid "Codeine"
msgstr "Codeine"
#. GenericName
#: codeine.desktop:5
msgid "Media Player"
msgstr "მედიადამკვრელი"
#. Comment
#: codeine.desktop:7
msgid "Video player for TDE designed to be as simple as possible"
msgstr ""
"ვიდეოდამკვრელი TDE-სთვის, რომელიც შეიქმნა, რომ ისეთი მარტივი ყოფილიყო, "
"როგორც ეს შესაძლებელია"
#. Comment
#: codeine_part.desktop:5
msgid "Embeddable Video Player"
msgstr "ჩაშენებადი ვიდეოდამკვრელი"
#. Name
#: codeine_play_dvd.desktop:8
msgid "Play DVD with Codeine"
msgstr "DVD-ის დაკვრა Codenie-ით"

@ -1,25 +1,26 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# This file is put in the public domain. # This file is put in the public domain.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # Toad114514 <xiaolan2332021@163.com>, 2025.
#
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-28 16:45+0200\n" "POT-Creation-Date: 2020-06-28 16:45+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: 2025-01-28 07:12+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: Toad114514 <xiaolan2332021@163.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: Chinese (Simplified) <https://mirror.git.trinitydesktop.org/"
"weblate/projects/applications/codeine-desktop-files/zh_Hans/>\n"
"Language: zh_CN\n" "Language: zh_CN\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.17\n"
#. Name #. Name
#: codeine.desktop:3 codeine_part.desktop:3 #: codeine.desktop:3 codeine_part.desktop:3
msgid "Codeine" msgid "Codeine"
msgstr "" msgstr "Codeine"
#. GenericName #. GenericName
#: codeine.desktop:5 #: codeine.desktop:5
@ -29,12 +30,12 @@ msgstr "媒体播放器"
#. Comment #. Comment
#: codeine.desktop:7 #: codeine.desktop:7
msgid "Video player for TDE designed to be as simple as possible" msgid "Video player for TDE designed to be as simple as possible"
msgstr "" msgstr "尽可能设计得简单的 TDE 视频播放器"
#. Comment #. Comment
#: codeine_part.desktop:5 #: codeine_part.desktop:5
msgid "Embeddable Video Player" msgid "Embeddable Video Player"
msgstr "" msgstr "内嵌视频播放器"
#. Name #. Name
#: codeine_play_dvd.desktop:8 #: codeine_play_dvd.desktop:8

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2020-07-26 20:37+0200\n" "POT-Creation-Date: 2025-05-11 18:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,26 +44,30 @@ msgstr ""
msgid "<b>Adjust video scale?" msgid "<b>Adjust video scale?"
msgstr "" msgstr ""
#: app/captureFrame.cpp:82 #: app/audioView.cpp:48 app/mainWindow.cpp:332
msgid "Show Analyzer"
msgstr ""
#: app/captureFrame.cpp:92
#, c-format #, c-format
msgid "Capture - %1" msgid "Capture - %1"
msgstr "" msgstr ""
#: app/captureFrame.cpp:98 #: app/captureFrame.cpp:108
msgid "" msgid ""
"*.png|PNG Format\n" "*.png|PNG Format\n"
"*.jpeg|JPEG Format" "*.jpeg|JPEG Format"
msgstr "" msgstr ""
#: app/captureFrame.cpp:100 #: app/captureFrame.cpp:110
msgid "Save Frame" msgid "Save Frame"
msgstr "" msgstr ""
#: app/captureFrame.cpp:111 #: app/captureFrame.cpp:121
msgid "%1 saved successfully" msgid "%1 saved successfully"
msgstr "" msgstr ""
#: app/captureFrame.cpp:113 #: app/captureFrame.cpp:123
#, c-format #, c-format
msgid "Sorry, could not save %1" msgid "Sorry, could not save %1"
msgstr "" msgstr ""
@ -80,19 +84,19 @@ msgstr ""
msgid "Determine &Automatically" msgid "Determine &Automatically"
msgstr "" msgstr ""
#: app/insertAspectRatioMenuItems.cpp:18 #: app/insertAspectRatioMenuItems.cpp:17
msgid "&Square (1:1)" msgid "&Square (1:1)"
msgstr "" msgstr ""
#: app/insertAspectRatioMenuItems.cpp:19 #: app/insertAspectRatioMenuItems.cpp:18
msgid "&4:3" msgid "&4:3"
msgstr "" msgstr ""
#: app/insertAspectRatioMenuItems.cpp:20 #: app/insertAspectRatioMenuItems.cpp:19
msgid "Ana&morphic (16:9)" msgid "Ana&morphic (16:9)"
msgstr "" msgstr ""
#: app/insertAspectRatioMenuItems.cpp:21 #: app/insertAspectRatioMenuItems.cpp:20
msgid "&DVB (2.11:1)" msgid "&DVB (2.11:1)"
msgstr "" msgstr ""
@ -132,79 +136,83 @@ msgstr ""
msgid "Patches, advice and moral support" msgid "Patches, advice and moral support"
msgstr "" msgstr ""
#: app/mainWindow.cpp:131 #: app/mainWindow.cpp:143
msgid "&Subtitles" msgid "Aspect Ratio"
msgstr "" msgstr ""
#: app/mainWindow.cpp:132 #: app/mainWindow.cpp:149
msgid "A&udio Channels" msgid "Audio Channels"
msgstr "" msgstr ""
#: app/mainWindow.cpp:133 #: app/mainWindow.cpp:155
msgid "Aspect &Ratio" msgid "Subtitles"
msgstr "" msgstr ""
#: app/mainWindow.cpp:250 #: app/mainWindow.cpp:277
msgid "Play &Media..." msgid "Play &Media..."
msgstr "" msgstr ""
#: app/mainWindow.cpp:256 #: app/mainWindow.cpp:283
msgid "Record" msgid "Record"
msgstr "" msgstr ""
#: app/mainWindow.cpp:258 #: app/mainWindow.cpp:285
msgid "Reset Video Scale" msgid "Reset Video Scale"
msgstr "" msgstr ""
#: app/mainWindow.cpp:259 app/mainWindow.cpp:592 #: app/mainWindow.cpp:286 app/mainWindow.cpp:650
msgid "Media Information" msgid "Media Information"
msgstr "" msgstr ""
#: app/mainWindow.cpp:260 #: app/mainWindow.cpp:287
msgid "Menu Toggle" msgid "Menu Toggle"
msgstr "" msgstr ""
#: app/mainWindow.cpp:261 #: app/mainWindow.cpp:288
msgid "&Capture Frame" msgid "&Capture Frame"
msgstr "" msgstr ""
#: app/mainWindow.cpp:263 #: app/mainWindow.cpp:290
msgid "Video Settings..." msgid "Video Settings..."
msgstr "" msgstr ""
#: app/mainWindow.cpp:264 #: app/mainWindow.cpp:291
msgid "Configure xine..." msgid "Configure xine..."
msgstr "" msgstr ""
#: app/mainWindow.cpp:266 #: app/mainWindow.cpp:293
msgid "Position Slider" msgid "Position Slider"
msgstr "" msgstr ""
#: app/mainWindow.cpp:364 #: app/mainWindow.cpp:295
msgid "Codeine was asked to open an empty URL; it cannot." msgid "A&udio Channels"
msgstr "" msgstr ""
#: app/mainWindow.cpp:426 #: app/mainWindow.cpp:298
msgid "Supported Media Formats" msgid "&Subtitles"
msgstr "" msgstr ""
#: app/mainWindow.cpp:426 #: app/mainWindow.cpp:301
msgid "All Files" msgid "Aspect &Ratio"
msgstr "" msgstr ""
#: app/mainWindow.cpp:427 #: app/mainWindow.cpp:425
msgid "Select A File To Play" msgid "Codeine was asked to open an empty URL; it cannot."
msgstr "" msgstr ""
#: app/mainWindow.cpp:607 #: app/mainWindow.cpp:487
msgid "&Determine Automatically" msgid "Supported Media Formats"
msgstr "" msgstr ""
#: app/mainWindow.cpp:619 #: app/mainWindow.cpp:487
msgid "&Off" msgid "All Files"
msgstr "" msgstr ""
#: app/mainWindow.cpp:661 #: app/mainWindow.cpp:488
msgid "Select A File To Play"
msgstr ""
#: app/mainWindow.cpp:714
msgid "Sorry, no media was found in the drop" msgid "Sorry, no media was found in the drop"
msgstr "" msgstr ""
@ -251,19 +259,19 @@ msgstr ""
msgid "Codeine could not open the file: %1" msgid "Codeine could not open the file: %1"
msgstr "" msgstr ""
#: app/stateChange.cpp:90 #: app/stateChange.cpp:92
msgid "&Pause" msgid "&Pause"
msgstr "" msgstr ""
#: app/stateChange.cpp:90 #: app/stateChange.cpp:92
msgid "&Play" msgid "&Play"
msgstr "" msgstr ""
#: app/stateChange.cpp:154 #: app/stateChange.cpp:171
msgid "No media loaded" msgid "No media loaded"
msgstr "" msgstr ""
#: app/stateChange.cpp:157 #: app/stateChange.cpp:174
msgid "Paused" msgid "Paused"
msgstr "" msgstr ""
@ -347,128 +355,128 @@ msgstr ""
msgid "Pause" msgid "Pause"
msgstr "" msgstr ""
#: app/volumeAction.cpp:45 #: app/volumeAction.cpp:32
msgid "Toggle Mute"
msgstr ""
#: app/volumeAction.cpp:62 part/part.cpp:39
msgid "Mute"
msgstr ""
#: app/volumeAction.cpp:87
msgid "Volume" msgid "Volume"
msgstr "" msgstr ""
#: app/volumeAction.cpp:85 #: app/volumeAction.cpp:127
#, c-format #, c-format
msgid "Volume: %1" msgid "Volume %1"
msgstr "" msgstr ""
#: app/xineConfig.cpp:62 #: app/xineConfig.cpp:46
msgid "Configure xine" msgid "Configure xine"
msgstr "" msgstr ""
#: app/xineConfig.cpp:87 #: app/xineConfig.cpp:68
msgid "" msgid ""
"xine's defaults are usually sensible and should not require modification. " "Xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)." "However, full configurability is provided for your pleasure ;-)"
msgstr "" msgstr ""
#: app/xineEngine.cpp:137 part/xineEngine.cpp:50 #: app/xineEngine.cpp:147 part/xineEngine.cpp:50
msgid "xine was unable to initialize any video-drivers." msgid "xine was unable to initialize any video-drivers."
msgstr "" msgstr ""
#: app/xineEngine.cpp:139 part/xineEngine.cpp:48 #: app/xineEngine.cpp:149 part/xineEngine.cpp:48
msgid "xine was unable to initialize any audio-drivers." msgid "xine was unable to initialize any audio-drivers."
msgstr "" msgstr ""
#: app/xineEngine.cpp:244 #: app/xineEngine.cpp:254
#, c-format #, c-format
msgid "Loading media: %1" msgid "Loading media: %1"
msgstr "" msgstr ""
#: app/xineEngine.cpp:349 #: app/xineEngine.cpp:360
#, c-format #, c-format
msgid "Recording to: %1" msgid "Recording to: %1"
msgstr "" msgstr ""
#: app/xineEngine.cpp:380 #: app/xineEngine.cpp:393
msgid "Playback paused" msgid "Playback paused"
msgstr "" msgstr ""
#: app/xineEngine.cpp:385 #: app/xineEngine.cpp:398
msgid "Playback resumed" msgid "Playback resumed"
msgstr "" msgstr ""
#: app/xineEngine.cpp:398 #: app/xineEngine.cpp:411
#, c-format #, c-format
msgid "There is no input plugin that can read: %1." msgid "There is no input plugin that can read: %1."
msgstr "" msgstr ""
#: app/xineEngine.cpp:401 #: app/xineEngine.cpp:414
#, c-format #, c-format
msgid "There is no demux plugin available for %1." msgid "There is no demux plugin available for %1."
msgstr "" msgstr ""
#: app/xineEngine.cpp:404 #: app/xineEngine.cpp:417
#, c-format #, c-format
msgid "Demuxing failed for %1." msgid "Demuxing failed for %1."
msgstr "" msgstr ""
#: app/xineEngine.cpp:409 #: app/xineEngine.cpp:422
#, c-format #, c-format
msgid "Internal error while attempting to play %1." msgid "Internal error while attempting to play %1."
msgstr "" msgstr ""
#: app/xineEngine.cpp:497 #: app/xineEngine.cpp:748 app/xineEngine.cpp:756
msgid "xine cannot currently seek in flac media"
msgstr ""
#: app/xineEngine.cpp:675 app/xineEngine.cpp:683
#, c-format #, c-format
msgid "Channel %1" msgid "Channel %1"
msgstr "" msgstr ""
#: app/xineEngine.cpp:782 part/xineEngine.cpp:289 #: app/xineEngine.cpp:855 part/xineEngine.cpp:289
msgid "The source is encrypted and can not be decrypted." msgid "The source is encrypted and can not be decrypted."
msgstr "" msgstr ""
#: app/xineEngine.cpp:784 part/xineEngine.cpp:291 #: app/xineEngine.cpp:857 part/xineEngine.cpp:291
msgid "The host is unknown for the URL: <i>%1</i>" msgid "The host is unknown for the URL: <i>%1</i>"
msgstr "" msgstr ""
#: app/xineEngine.cpp:786 part/xineEngine.cpp:293 #: app/xineEngine.cpp:859 part/xineEngine.cpp:293
msgid "The device name you specified seems invalid." msgid "The device name you specified seems invalid."
msgstr "" msgstr ""
#: app/xineEngine.cpp:788 part/xineEngine.cpp:295 #: app/xineEngine.cpp:861 part/xineEngine.cpp:295
msgid "The network appears unreachable." msgid "The network appears unreachable."
msgstr "" msgstr ""
#: app/xineEngine.cpp:790 part/xineEngine.cpp:297 #: app/xineEngine.cpp:863 part/xineEngine.cpp:297
msgid "Audio output unavailable; the device is busy." msgid "Audio output unavailable; the device is busy."
msgstr "" msgstr ""
#: app/xineEngine.cpp:792 part/xineEngine.cpp:299 #: app/xineEngine.cpp:865 part/xineEngine.cpp:299
msgid "The connection was refused for the URL: <i>%1</i>" msgid "The connection was refused for the URL: <i>%1</i>"
msgstr "" msgstr ""
#: app/xineEngine.cpp:794 part/xineEngine.cpp:301 #: app/xineEngine.cpp:867 part/xineEngine.cpp:301
msgid "xine could not find the URL: <i>%1</i>" msgid "xine could not find the URL: <i>%1</i>"
msgstr "" msgstr ""
#: app/xineEngine.cpp:796 part/xineEngine.cpp:303 #: app/xineEngine.cpp:869 part/xineEngine.cpp:303
msgid "Access was denied for the URL: <i>%1</i>" msgid "Access was denied for the URL: <i>%1</i>"
msgstr "" msgstr ""
#: app/xineEngine.cpp:798 part/xineEngine.cpp:305 #: app/xineEngine.cpp:871 part/xineEngine.cpp:305
msgid "The source cannot be read for the URL: <i>%1</i>" msgid "The source cannot be read for the URL: <i>%1</i>"
msgstr "" msgstr ""
#: app/xineEngine.cpp:800 part/xineEngine.cpp:307 #: app/xineEngine.cpp:873 part/xineEngine.cpp:307
msgid "A problem occurred while loading a library or decoder." msgid "A problem occurred while loading a library or decoder."
msgstr "" msgstr ""
#: app/xineEngine.cpp:827 part/xineEngine.cpp:334 #: app/xineEngine.cpp:900 part/xineEngine.cpp:334
msgid "Sorry, no additional information is available." msgid "Sorry, no additional information is available."
msgstr "" msgstr ""
#: part/part.cpp:39
msgid "Mute"
msgstr ""
#: part/xineEngine.cpp:166 #: part/xineEngine.cpp:166
msgid "The Codeine video player could not find an input plugin for '%1'." msgid "The Codeine video player could not find an input plugin for '%1'."
msgstr "" msgstr ""

@ -0,0 +1,506 @@
# SOME DESCRIPTIVE TITLE.
# Temuri Doghonadze <rkavt@smartprojects.ge>, 2024, 2025.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-05-11 18:19+0000\n"
"PO-Revision-Date: 2025-03-26 06:44+0000\n"
"Last-Translator: Temuri Doghonadze <rkavt@smartprojects.ge>\n"
"Language-Team: Georgian <https://mirror.git.trinitydesktop.org/weblate/"
"projects/applications/codeine/ka/>\n"
"Language: ka\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. Instead of a literal translation, add your name to the end of the list (separated by a comma).
msgid ""
"_: NAME OF TRANSLATORS\n"
"Your names"
msgstr "თემური დოღონაძე"
#. Instead of a literal translation, add your email to the end of the list (separated by a comma).
msgid ""
"_: EMAIL OF TRANSLATORS\n"
"Your emails"
msgstr "temuri.doghonadze@gmail.com"
#: app/actions.cpp:15 part/part.cpp:38
msgid "Play"
msgstr "დაკვრა"
#: app/adjustSizeButton.cpp:31
msgid "Preferred Scale"
msgstr "რჩეულ მასშტაბი"
#: app/adjustSizeButton.cpp:35
#, c-format
msgid "Scale 100%"
msgstr "100%-მდე გადიდება"
#: app/adjustSizeButton.cpp:41
msgid "<b>Adjust video scale?"
msgstr "<b>გავასწორო ვიდეოს მასშტაბი?"
#: app/audioView.cpp:48 app/mainWindow.cpp:332
msgid "Show Analyzer"
msgstr "ანალიზატორის ჩვენება"
#: app/captureFrame.cpp:92
#, c-format
msgid "Capture - %1"
msgstr "ჩაწერა - %1"
#: app/captureFrame.cpp:108
msgid ""
"*.png|PNG Format\n"
"*.jpeg|JPEG Format"
msgstr ""
"*.png|PNG ფორმატი\n"
"*.jpeg|JPEG ფორმატი"
#: app/captureFrame.cpp:110
msgid "Save Frame"
msgstr "კადრის შენახვა"
#: app/captureFrame.cpp:121
msgid "%1 saved successfully"
msgstr "%1-ის შენახვა წარმატებულია"
#: app/captureFrame.cpp:123
#, c-format
msgid "Sorry, could not save %1"
msgstr "უკაცრავად, შენახვის შეცდომა %1-სთვის"
#: app/fullScreenAction.cpp:31
msgid "Exit F&ull Screen Mode"
msgstr "სრული &ეკრანის რეჟიმიდან გასვლა"
#: app/fullScreenAction.cpp:37
msgid "F&ull Screen Mode"
msgstr "&სრულ-ეკრანზე"
#: app/insertAspectRatioMenuItems.cpp:16
msgid "Determine &Automatically"
msgstr "ავტომატურად &განსაზღვრა"
#: app/insertAspectRatioMenuItems.cpp:17
msgid "&Square (1:1)"
msgstr "&კვადრატი (1:1)"
#: app/insertAspectRatioMenuItems.cpp:18
msgid "&4:3"
msgstr "&4:3"
#: app/insertAspectRatioMenuItems.cpp:19
msgid "Ana&morphic (16:9)"
msgstr "&ანამორფული (16:9)"
#: app/insertAspectRatioMenuItems.cpp:20
msgid "&DVB (2.11:1)"
msgstr "&DVB (2.11:1)"
#: app/main.cpp:14
msgid "A video player that has a usability focus"
msgstr "ვიდეო დამკვრელი ფოკუსით გამოყენებადობაზე"
#: app/main.cpp:15
msgid "Copyright 2006, Max Howell"
msgstr "ყველა უფლება დაცულია, 2006, Max Howell"
#: app/main.cpp:20
msgid "Play 'URL'"
msgstr "URL-ის დაკვრა"
#: app/main.cpp:21
msgid "Play DVD Video"
msgstr "DVD ვიდეოს დაკვრა"
#: app/main.cpp:31
msgid "Handbook"
msgstr "სახელმძღვანელო"
#: app/main.cpp:32
msgid "Great reference code"
msgstr "დიდი მიმართვის კოდი"
#: app/main.cpp:33
msgid "The video for \"Call on Me\" encouraged plenty of debugging! ;)"
msgstr "ვიდეომ \"დამირეკე\" ბევრი შეცდომის გასწორება გვაიძულა! ;)"
#: app/main.cpp:34
msgid "The current Codeine icon"
msgstr "Codeine-ის მიმდინარე ხატულა"
#: app/main.cpp:35
msgid "Patches, advice and moral support"
msgstr "პაჩები, რჩევები და მორალური მხარდაჭერა"
#: app/mainWindow.cpp:143
msgid "Aspect Ratio"
msgstr "თანაფარდობა"
#: app/mainWindow.cpp:149
msgid "Audio Channels"
msgstr "აუდიო არხები"
#: app/mainWindow.cpp:155
msgid "Subtitles"
msgstr "სუბტიტრები"
#: app/mainWindow.cpp:277
msgid "Play &Media..."
msgstr "მედიის &დაკვრა..."
#: app/mainWindow.cpp:283
msgid "Record"
msgstr "ჩაწერა"
#: app/mainWindow.cpp:285
msgid "Reset Video Scale"
msgstr "ვიდეოს მასშტაბის ჩამოყრა"
#: app/mainWindow.cpp:286 app/mainWindow.cpp:650
msgid "Media Information"
msgstr "მედიის ინფორმაცია"
#: app/mainWindow.cpp:287
msgid "Menu Toggle"
msgstr "მენიუს გადართვა"
#: app/mainWindow.cpp:288
msgid "&Capture Frame"
msgstr "&კადრის ჩაწერა"
#: app/mainWindow.cpp:290
msgid "Video Settings..."
msgstr "ვიდეოს მორგება..."
#: app/mainWindow.cpp:291
msgid "Configure xine..."
msgstr "Xine-ის მორგება..."
#: app/mainWindow.cpp:293
msgid "Position Slider"
msgstr "მდებარეობის ცოცია"
#: app/mainWindow.cpp:295
msgid "A&udio Channels"
msgstr "ა&უდიო არხები"
#: app/mainWindow.cpp:298
msgid "&Subtitles"
msgstr "&სუბტიტრები"
#: app/mainWindow.cpp:301
msgid "Aspect &Ratio"
msgstr "ასპექტის &ფარდობა"
#: app/mainWindow.cpp:425
msgid "Codeine was asked to open an empty URL; it cannot."
msgstr "Codeine-ს სთხოვეს, ცარიელი URL გაეხსნა. მას ეს არ შეუძლია."
#: app/mainWindow.cpp:487
msgid "Supported Media Formats"
msgstr "მხარდაჭერილი მედია ფორმატები"
#: app/mainWindow.cpp:487
msgid "All Files"
msgstr "ყველა ფაილი"
#: app/mainWindow.cpp:488
msgid "Select A File To Play"
msgstr "აირჩიეთ დასაკრავი ფაილი"
#: app/mainWindow.cpp:714
msgid "Sorry, no media was found in the drop"
msgstr "რაც დააგდეთ, მასში მედიაფაილი ვერ ვიპოვე"
#: app/playDialog.cpp:28
msgid "Play Media"
msgstr "მედიის დაკვრა"
#: app/playDialog.cpp:34
msgid "What media would you like to play?"
msgstr "რისი დაკვრა გსურთ?"
#: app/playDialog.cpp:39
msgid "Play File..."
msgstr "ფაილის დაკვრა..."
#: app/playDialog.cpp:43
msgid "Play VCD"
msgstr "VCD-ს დაკვრა"
#: app/playDialog.cpp:47
msgid "Play DVD"
msgstr "DVD-ის დაკვრა"
#: app/playDialog.cpp:75
msgid "Recently Played Media"
msgstr "ახლახან დაკრული მედია"
#: app/playlistFile.cpp:32
msgid "The file is not a playlist"
msgstr "ეს ფაილი დასაკრავ სიაში არაა"
#: app/playlistFile.cpp:39
#, c-format
msgid "Codeine could not download the remote playlist: %1"
msgstr "Codeine-მა ვერ გადმოწერა დასაკრავი სია ინტერნეტიდან: %1"
#: app/playlistFile.cpp:54
msgid ""
"<qt>The playlist, <i>'%1'</i>, could not be interpreted. Perhaps it is empty?"
msgstr ""
"<qt>დასაკრავი სიის, <i>'%1'</i>, ინტერპრეტაცია შეუძლებელია. ცარიელი ხომ არაა?"
#: app/playlistFile.cpp:58
#, c-format
msgid "Codeine could not open the file: %1"
msgstr "Codeine-მა ვერ გახსნა ფაილი: %1"
#: app/stateChange.cpp:92
msgid "&Pause"
msgstr "&შეჩერება"
#: app/stateChange.cpp:92
msgid "&Play"
msgstr "&დაკვრა"
#: app/stateChange.cpp:171
msgid "No media loaded"
msgstr "მედია ჩატვირთული არაა"
#: app/stateChange.cpp:174
msgid "Paused"
msgstr "შეჩერებულია"
#: app/theStream.cpp:108
msgid "Metadata"
msgstr "მეტამონაცემები"
#: app/theStream.cpp:110
msgid "Title"
msgstr "სათაური"
#: app/theStream.cpp:111
msgid "Comment"
msgstr "კომენტარი"
#: app/theStream.cpp:112
msgid "Artist"
msgstr "შემსრულებელი"
#: app/theStream.cpp:113
msgid "Genre"
msgstr "ჟანრი"
#: app/theStream.cpp:114
msgid "Album"
msgstr "ალბომი"
#: app/theStream.cpp:115
msgid "Year"
msgstr "წელი"
#: app/theStream.cpp:117
msgid "Audio Properties"
msgstr "აუდიო თვისებები"
#: app/theStream.cpp:119
msgid "Bitrate"
msgstr "სიჩქარე"
#: app/theStream.cpp:119
msgid "%1 bps"
msgstr "%1 ბ/წმ"
#: app/theStream.cpp:120
msgid "Sample-rate"
msgstr "სემპლის-სიხშირე"
#: app/theStream.cpp:120
msgid "%1 Hz"
msgstr "%1 ჰც"
#: app/theStream.cpp:122
msgid "Technical Information"
msgstr "ტექნიკური ინფორმაცია"
#: app/theStream.cpp:124
msgid "Video Codec"
msgstr "ვიდეო კოდეკი"
#: app/theStream.cpp:125
msgid "Audio Codec"
msgstr "აუდიო კოდეკი"
#: app/theStream.cpp:126
msgid "System Layer"
msgstr "სისტემის ფენა"
#: app/theStream.cpp:127
msgid "Input Plugin"
msgstr "შეყვანის დამატება"
#: app/theStream.cpp:128
msgid "CDINDEX_DISCID"
msgstr "CDINDEX_DISCID"
#: app/videoSettings.cpp:92
msgid "Video Settings"
msgstr "ვიდეოს პარამეტრები"
#: app/videoWindow.cpp:136
msgid "Pause"
msgstr "შეჩერება"
#: app/volumeAction.cpp:32
msgid "Toggle Mute"
msgstr ""
#: app/volumeAction.cpp:62 part/part.cpp:39
msgid "Mute"
msgstr "დადუმება"
#: app/volumeAction.cpp:87
msgid "Volume"
msgstr "ხმა"
#: app/volumeAction.cpp:127
#, c-format
msgid "Volume %1"
msgstr "ხმა %1"
#: app/xineConfig.cpp:46
msgid "Configure xine"
msgstr "Xine-ის მორგება"
#: app/xineConfig.cpp:68
msgid ""
"Xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)"
msgstr ""
"Xine-ის ნაგულისხმევ მნიშვნელობებს ჩვეულებრივ შეცვლა არ სჭირდება. მაგრამ, "
"თქვენი სიამოვნებისთვის, ჩვენ სრული მორგებადობა ჩავდეთ ;-)"
#: app/xineEngine.cpp:147 part/xineEngine.cpp:50
msgid "xine was unable to initialize any video-drivers."
msgstr "xine-ის შეცდომა ვიდეოდრაივერბის ინიციალიზაციისას."
#: app/xineEngine.cpp:149 part/xineEngine.cpp:48
msgid "xine was unable to initialize any audio-drivers."
msgstr "xine-ის შეცდომა აუდიოდრაივერების ინიციალიზაციისას."
#: app/xineEngine.cpp:254
#, c-format
msgid "Loading media: %1"
msgstr "იტვირთება მედია: %1"
#: app/xineEngine.cpp:360
#, c-format
msgid "Recording to: %1"
msgstr "ჩაწერა ფაილში: %1"
#: app/xineEngine.cpp:393
msgid "Playback paused"
msgstr "დაკვრა შეჩერებულია"
#: app/xineEngine.cpp:398
msgid "Playback resumed"
msgstr "დაკვრა გაგრძელდა"
#: app/xineEngine.cpp:411
#, c-format
msgid "There is no input plugin that can read: %1."
msgstr "არ არსებობს შეყვანის დამატება, რომელსაც შეუძლია, წაიკითხოს: %1."
#: app/xineEngine.cpp:414
#, c-format
msgid "There is no demux plugin available for %1."
msgstr "Demux დამატება ხელმიუწვდომელია %1-სთვის."
#: app/xineEngine.cpp:417
#, c-format
msgid "Demuxing failed for %1."
msgstr "Demux ჩავარდა ფაილისთვის %1."
#: app/xineEngine.cpp:422
#, c-format
msgid "Internal error while attempting to play %1."
msgstr "შიდა შეცდომა %1-ის დაკვრის მცდელობისას."
#: app/xineEngine.cpp:748 app/xineEngine.cpp:756
#, c-format
msgid "Channel %1"
msgstr "არხი %1"
#: app/xineEngine.cpp:855 part/xineEngine.cpp:289
msgid "The source is encrypted and can not be decrypted."
msgstr "წყარო დაშიფრულია და მისი გაშიფვრა შეუძლებელია."
#: app/xineEngine.cpp:857 part/xineEngine.cpp:291
msgid "The host is unknown for the URL: <i>%1</i>"
msgstr "ჰოსტის სახელი უცნობია URL-სთვის <i>%1</i>"
#: app/xineEngine.cpp:859 part/xineEngine.cpp:293
msgid "The device name you specified seems invalid."
msgstr "თქვენს მიერ მითითებული მოწყობილობის სახელი არასწორია."
#: app/xineEngine.cpp:861 part/xineEngine.cpp:295
msgid "The network appears unreachable."
msgstr "როგორც ჩანს, ქსელი ხელმიუწვდომელია."
#: app/xineEngine.cpp:863 part/xineEngine.cpp:297
msgid "Audio output unavailable; the device is busy."
msgstr "აუდიოს გამოტანა ხელმიუწვდომელია, რადგან მოწყობილობა დაკავებულია."
#: app/xineEngine.cpp:865 part/xineEngine.cpp:299
msgid "The connection was refused for the URL: <i>%1</i>"
msgstr "მიერთება უარყოფილია URL-სთვის: <i>%1</i>"
#: app/xineEngine.cpp:867 part/xineEngine.cpp:301
msgid "xine could not find the URL: <i>%1</i>"
msgstr "xine-მა ვერ იპოვა URL: <i>%1</i>"
#: app/xineEngine.cpp:869 part/xineEngine.cpp:303
msgid "Access was denied for the URL: <i>%1</i>"
msgstr "წვდომა მისამართზე აკრძალულია: <i>%1</i>"
#: app/xineEngine.cpp:871 part/xineEngine.cpp:305
msgid "The source cannot be read for the URL: <i>%1</i>"
msgstr "წყარო URL-თვის ვერ იქნა წაკითხული: <i>%1</i>"
#: app/xineEngine.cpp:873 part/xineEngine.cpp:307
msgid "A problem occurred while loading a library or decoder."
msgstr "პრობლემა ბიბლიოთეკის ან დეკოდერის ჩატვირთვისას."
#: app/xineEngine.cpp:900 part/xineEngine.cpp:334
msgid "Sorry, no additional information is available."
msgstr "ბოდიში, დამატებითი ინფორმაცია არაა ხელმისაწვდომი."
#: part/xineEngine.cpp:166
msgid "The Codeine video player could not find an input plugin for '%1'."
msgstr "ვიდეოდამკვრელმა Codeine ვერ იპოვა შეყვანის დამატება ფაილისთვის '%1'."
#: part/xineEngine.cpp:169
msgid "The Codeine video player could not find a demux plugin for '%1'."
msgstr "ვიდეოდამკვრელმა Codeine ვერ იპოვა demux დამატება ფაილისთვის '%1'."
#: part/xineEngine.cpp:172
msgid ""
"The Codeine video player failed to demux '%1'; please check your xine "
"installation."
msgstr ""
"ვიდეოდამკვრელის Codeine demux-ის შეცდომა '%1'-სთვის. შეამოწმეთ xine-ის "
"ფაილები."
#: part/xineEngine.cpp:177
msgid ""
"The Codeine video player reports an internal error; please check your xine "
"installation."
msgstr ""
"ვიდეოდამკვრელმა Codeine შიდა შეცდომა დააბრუნა. შეამოწმეთ xine-ის ფაილები."

@ -0,0 +1,507 @@
# SOME DESCRIPTIVE TITLE.
# Heimen Stoffels <vistausss@fastmail.com>, 2025.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-05-11 18:19+0000\n"
"PO-Revision-Date: 2025-05-12 18:44+0000\n"
"Last-Translator: Heimen Stoffels <vistausss@fastmail.com>\n"
"Language-Team: Dutch <https://mirror.git.trinitydesktop.org/weblate/projects/"
"applications/codeine/nl/>\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. Instead of a literal translation, add your name to the end of the list (separated by a comma).
msgid ""
"_: NAME OF TRANSLATORS\n"
"Your names"
msgstr "Heimen Stoffels"
#. Instead of a literal translation, add your email to the end of the list (separated by a comma).
msgid ""
"_: EMAIL OF TRANSLATORS\n"
"Your emails"
msgstr "vistausss@fastmail.com"
#: app/actions.cpp:15 part/part.cpp:38
msgid "Play"
msgstr "Afspelen"
#: app/adjustSizeButton.cpp:31
msgid "Preferred Scale"
msgstr "Voorkeursgrootte"
#: app/adjustSizeButton.cpp:35
#, c-format
msgid "Scale 100%"
msgstr "100%"
#: app/adjustSizeButton.cpp:41
msgid "<b>Adjust video scale?"
msgstr "<b>Wilt u de videogrootte aanpassen?"
#: app/audioView.cpp:48 app/mainWindow.cpp:332
msgid "Show Analyzer"
msgstr "Analyse tonen"
#: app/captureFrame.cpp:92
#, c-format
msgid "Capture - %1"
msgstr "Opname - %1"
#: app/captureFrame.cpp:108
msgid ""
"*.png|PNG Format\n"
"*.jpeg|JPEG Format"
msgstr ""
"*.png|png-formaat\n"
"*.jpeg|jpeg-formaat"
#: app/captureFrame.cpp:110
msgid "Save Frame"
msgstr "Frame opslaan"
#: app/captureFrame.cpp:121
msgid "%1 saved successfully"
msgstr "%1 is opgeslagen"
#: app/captureFrame.cpp:123
#, c-format
msgid "Sorry, could not save %1"
msgstr "%1 kan niet worden opgeslagen"
#: app/fullScreenAction.cpp:31
msgid "Exit F&ull Screen Mode"
msgstr "Schermv&ullende weergave sluiten"
#: app/fullScreenAction.cpp:37
msgid "F&ull Screen Mode"
msgstr "Schermv&ullende weergave"
#: app/insertAspectRatioMenuItems.cpp:16
msgid "Determine &Automatically"
msgstr "&Automatisch vaststellen"
#: app/insertAspectRatioMenuItems.cpp:17
msgid "&Square (1:1)"
msgstr "&Vierkant (1:1)"
#: app/insertAspectRatioMenuItems.cpp:18
msgid "&4:3"
msgstr "&4:3"
#: app/insertAspectRatioMenuItems.cpp:19
msgid "Ana&morphic (16:9)"
msgstr "Ana&morfisch (16:9)"
#: app/insertAspectRatioMenuItems.cpp:20
msgid "&DVB (2.11:1)"
msgstr "&DVB (2.11:1)"
#: app/main.cpp:14
msgid "A video player that has a usability focus"
msgstr "Een zeer gebruiksvriendelijke videospeler"
#: app/main.cpp:15
msgid "Copyright 2006, Max Howell"
msgstr "Copyright 2006, Max Howell"
#: app/main.cpp:20
msgid "Play 'URL'"
msgstr "Url afspelen"
#: app/main.cpp:21
msgid "Play DVD Video"
msgstr "Dvd-video afspelen"
#: app/main.cpp:31
msgid "Handbook"
msgstr "Handleiding"
#: app/main.cpp:32
msgid "Great reference code"
msgstr "Goede referentiecode"
#: app/main.cpp:33
msgid "The video for \"Call on Me\" encouraged plenty of debugging! ;)"
msgstr ""
"De videoclip van Call on Me stimuleerde me om veel fouten op te sporen! ;)"
#: app/main.cpp:34
msgid "The current Codeine icon"
msgstr "Het huidige Codeine-pictogram"
#: app/main.cpp:35
msgid "Patches, advice and moral support"
msgstr "Patches, advies en morele ondersteuning"
#: app/mainWindow.cpp:143
msgid "Aspect Ratio"
msgstr "Beeldverhouding"
#: app/mainWindow.cpp:149
msgid "Audio Channels"
msgstr "Aantal audiokanalen"
#: app/mainWindow.cpp:155
msgid "Subtitles"
msgstr "Ondertiteling"
#: app/mainWindow.cpp:277
msgid "Play &Media..."
msgstr "&Media afspelen…"
#: app/mainWindow.cpp:283
msgid "Record"
msgstr "Opnemen"
#: app/mainWindow.cpp:285
msgid "Reset Video Scale"
msgstr "Standaard videogrootte"
#: app/mainWindow.cpp:286 app/mainWindow.cpp:650
msgid "Media Information"
msgstr "Media-informatie"
#: app/mainWindow.cpp:287
msgid "Menu Toggle"
msgstr "Menu tonen/verbergen"
#: app/mainWindow.cpp:288
msgid "&Capture Frame"
msgstr "Frame &vastleggen"
#: app/mainWindow.cpp:290
msgid "Video Settings..."
msgstr "Video-instellingen…"
#: app/mainWindow.cpp:291
msgid "Configure xine..."
msgstr "Xine instellen…"
#: app/mainWindow.cpp:293
msgid "Position Slider"
msgstr "Positieschuif"
#: app/mainWindow.cpp:295
msgid "A&udio Channels"
msgstr "A&udiokanalen"
#: app/mainWindow.cpp:298
msgid "&Subtitles"
msgstr "Onder&titeling"
#: app/mainWindow.cpp:301
msgid "Aspect &Ratio"
msgstr "Beeldve&rhouding"
#: app/mainWindow.cpp:425
msgid "Codeine was asked to open an empty URL; it cannot."
msgstr "Codeine kan geen inhoudsloze url's openen."
#: app/mainWindow.cpp:487
msgid "Supported Media Formats"
msgstr "Ondersteunde mediaformaten"
#: app/mainWindow.cpp:487
msgid "All Files"
msgstr "Alle bestanden"
#: app/mainWindow.cpp:488
msgid "Select A File To Play"
msgstr "Kies een af te spelen bestand"
#: app/mainWindow.cpp:714
msgid "Sorry, no media was found in the drop"
msgstr "Er is geen media aangetroffen in het bestand"
#: app/playDialog.cpp:28
msgid "Play Media"
msgstr "Media afspelen"
#: app/playDialog.cpp:34
msgid "What media would you like to play?"
msgstr "Wat voor soort media wilt u afspelen?"
#: app/playDialog.cpp:39
msgid "Play File..."
msgstr "Bestand afspelen…"
#: app/playDialog.cpp:43
msgid "Play VCD"
msgstr "Vcd afspelen"
#: app/playDialog.cpp:47
msgid "Play DVD"
msgstr "Dvd afspelen"
#: app/playDialog.cpp:75
msgid "Recently Played Media"
msgstr "Onlangs afgespeelde media"
#: app/playlistFile.cpp:32
msgid "The file is not a playlist"
msgstr "Dit bestand is geen afspeellijst"
#: app/playlistFile.cpp:39
#, c-format
msgid "Codeine could not download the remote playlist: %1"
msgstr "De externe afspeellijst kan niet worden opgehaald: %1"
#: app/playlistFile.cpp:54
msgid ""
"<qt>The playlist, <i>'%1'</i>, could not be interpreted. Perhaps it is empty?"
msgstr ""
"<qt>De afspeellijst, <i>%1</i>, kan niet worden verwerkt. Is de lijst blanco?"
#: app/playlistFile.cpp:58
#, c-format
msgid "Codeine could not open the file: %1"
msgstr "Het bestand kan niet worden geopend: %1"
#: app/stateChange.cpp:92
msgid "&Pause"
msgstr "&Pauzeren"
#: app/stateChange.cpp:92
msgid "&Play"
msgstr "Afs&pelen"
#: app/stateChange.cpp:171
msgid "No media loaded"
msgstr "Er is geen media geladen"
#: app/stateChange.cpp:174
msgid "Paused"
msgstr "Gepauzeerd"
#: app/theStream.cpp:108
msgid "Metadata"
msgstr "Metagegevens"
#: app/theStream.cpp:110
msgid "Title"
msgstr "Titel"
#: app/theStream.cpp:111
msgid "Comment"
msgstr "Opmerking"
#: app/theStream.cpp:112
msgid "Artist"
msgstr "Artiest"
#: app/theStream.cpp:113
msgid "Genre"
msgstr "Genre"
#: app/theStream.cpp:114
msgid "Album"
msgstr "Album"
#: app/theStream.cpp:115
msgid "Year"
msgstr "Jaar"
#: app/theStream.cpp:117
msgid "Audio Properties"
msgstr "Audio-informatie"
#: app/theStream.cpp:119
msgid "Bitrate"
msgstr "Bitsnelheid"
#: app/theStream.cpp:119
msgid "%1 bps"
msgstr "%1 bps"
#: app/theStream.cpp:120
msgid "Sample-rate"
msgstr "Samplesnelheid"
#: app/theStream.cpp:120
msgid "%1 Hz"
msgstr "%1 Hz"
#: app/theStream.cpp:122
msgid "Technical Information"
msgstr "Technische informatie"
#: app/theStream.cpp:124
msgid "Video Codec"
msgstr "Videocodec"
#: app/theStream.cpp:125
msgid "Audio Codec"
msgstr "Audiocodec"
#: app/theStream.cpp:126
msgid "System Layer"
msgstr "Systeemlaag"
#: app/theStream.cpp:127
msgid "Input Plugin"
msgstr "Invoerplug-in"
#: app/theStream.cpp:128
msgid "CDINDEX_DISCID"
msgstr "CDINDEX_DISCID"
#: app/videoSettings.cpp:92
msgid "Video Settings"
msgstr "Video-instellingen"
#: app/videoWindow.cpp:136
msgid "Pause"
msgstr "Pauzeren"
#: app/volumeAction.cpp:32
msgid "Toggle Mute"
msgstr "Dempen aan/uit"
#: app/volumeAction.cpp:62 part/part.cpp:39
msgid "Mute"
msgstr "Dempen"
#: app/volumeAction.cpp:87
msgid "Volume"
msgstr "Volumeniveau"
#: app/volumeAction.cpp:127
#, c-format
msgid "Volume %1"
msgstr "Volumeniveau: %"
#: app/xineConfig.cpp:46
msgid "Configure xine"
msgstr "Xine instellen"
#: app/xineConfig.cpp:68
msgid ""
"Xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)"
msgstr ""
"Xine's standaardinstellingen zijn goed doordacht en hoeven niet bewerkt te "
"worden. Mocht u van mening verschillen, dan staat het u vrij dat alsnog te "
"doen. ;-)"
#: app/xineEngine.cpp:147 part/xineEngine.cpp:50
msgid "xine was unable to initialize any video-drivers."
msgstr "Xine kan de videostuuprogramma's niet starten."
#: app/xineEngine.cpp:149 part/xineEngine.cpp:48
msgid "xine was unable to initialize any audio-drivers."
msgstr "Xine kan de audiostuurprogramma's niet starten."
#: app/xineEngine.cpp:254
#, c-format
msgid "Loading media: %1"
msgstr "Media openen: %1"
#: app/xineEngine.cpp:360
#, c-format
msgid "Recording to: %1"
msgstr "Opname opslaan in: %1"
#: app/xineEngine.cpp:393
msgid "Playback paused"
msgstr "Afspelen gepauzeerd"
#: app/xineEngine.cpp:398
msgid "Playback resumed"
msgstr "Afspelen hervat"
#: app/xineEngine.cpp:411
#, c-format
msgid "There is no input plugin that can read: %1."
msgstr "Er is geen invoerplug-in die %1 kan uitlezen."
#: app/xineEngine.cpp:414
#, c-format
msgid "There is no demux plugin available for %1."
msgstr "Er is geen demuxplug-in beschikbaar voor %1."
#: app/xineEngine.cpp:417
#, c-format
msgid "Demuxing failed for %1."
msgstr "Het demuxen van %1 is mislukt."
#: app/xineEngine.cpp:422
#, c-format
msgid "Internal error while attempting to play %1."
msgstr "Er is een interne fout opgetreden tijdens het starten van %1."
#: app/xineEngine.cpp:748 app/xineEngine.cpp:756
#, c-format
msgid "Channel %1"
msgstr "Kanaal %1"
#: app/xineEngine.cpp:855 part/xineEngine.cpp:289
msgid "The source is encrypted and can not be decrypted."
msgstr "De bron is beveiligd en kan niet worden ontsleuteld."
#: app/xineEngine.cpp:857 part/xineEngine.cpp:291
msgid "The host is unknown for the URL: <i>%1</i>"
msgstr "Er is geen host bekend van de url: <i>%1</i>"
#: app/xineEngine.cpp:859 part/xineEngine.cpp:293
msgid "The device name you specified seems invalid."
msgstr "De apparaatnaam lijkt ongeldig te zijn."
#: app/xineEngine.cpp:861 part/xineEngine.cpp:295
msgid "The network appears unreachable."
msgstr "Er lijkt geen internetverbinding te zijn."
#: app/xineEngine.cpp:863 part/xineEngine.cpp:297
msgid "Audio output unavailable; the device is busy."
msgstr "De audio-uitvoer is niet beschikbaar, omdat het apparaat bezig is."
#: app/xineEngine.cpp:865 part/xineEngine.cpp:299
msgid "The connection was refused for the URL: <i>%1</i>"
msgstr "De verbinding met <i>%1</i> is geweigerd."
#: app/xineEngine.cpp:867 part/xineEngine.cpp:301
msgid "xine could not find the URL: <i>%1</i>"
msgstr "Xine kan deze url niet openen: <i>%1</i>"
#: app/xineEngine.cpp:869 part/xineEngine.cpp:303
msgid "Access was denied for the URL: <i>%1</i>"
msgstr "De toegang tot <i>%1</i> is geweigerd."
#: app/xineEngine.cpp:871 part/xineEngine.cpp:305
msgid "The source cannot be read for the URL: <i>%1</i>"
msgstr "De bron van <i>%1</i> kan niet worden uitgelezen."
#: app/xineEngine.cpp:873 part/xineEngine.cpp:307
msgid "A problem occurred while loading a library or decoder."
msgstr ""
"Er is een probleem opgetreden tijdens het laden van een bibliotheek of "
"decodeerplug-in."
#: app/xineEngine.cpp:900 part/xineEngine.cpp:334
msgid "Sorry, no additional information is available."
msgstr "Er is geen aanvullende informatie beschikbaar."
#: part/xineEngine.cpp:166
msgid "The Codeine video player could not find an input plugin for '%1'."
msgstr "Er is geen invoerplug-in gevonden voor %1."
#: part/xineEngine.cpp:169
msgid "The Codeine video player could not find a demux plugin for '%1'."
msgstr "Er is geen demuxplug-in gevonden voor %1."
#: part/xineEngine.cpp:172
msgid ""
"The Codeine video player failed to demux '%1'; please check your xine "
"installation."
msgstr "%1 kan niet worden gedemuxet - controleer uw Xine-installatie."
#: part/xineEngine.cpp:177
msgid ""
"The Codeine video player reports an internal error; please check your xine "
"installation."
msgstr "Er is een interne fout opgetreden - controleer uw Xine-installatie."

@ -0,0 +1,500 @@
# SOME DESCRIPTIVE TITLE.
# Toad114514 <xiaolan2332021@163.com>, 2025.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-05-11 18:19+0000\n"
"PO-Revision-Date: 2025-04-21 05:15+0000\n"
"Last-Translator: Toad114514 <xiaolan2332021@163.com>\n"
"Language-Team: Chinese (Simplified) <https://mirror.git.trinitydesktop.org/"
"weblate/projects/applications/codeine/zh_Hans/>\n"
"Language: zh_Hans\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.17\n"
#. Instead of a literal translation, add your name to the end of the list (separated by a comma).
msgid ""
"_: NAME OF TRANSLATORS\n"
"Your names"
msgstr "Toad114514"
#. Instead of a literal translation, add your email to the end of the list (separated by a comma).
msgid ""
"_: EMAIL OF TRANSLATORS\n"
"Your emails"
msgstr "xiaolan2332021@163.com"
#: app/actions.cpp:15 part/part.cpp:38
msgid "Play"
msgstr "播放"
#: app/adjustSizeButton.cpp:31
msgid "Preferred Scale"
msgstr "首选缩放"
#: app/adjustSizeButton.cpp:35
#, c-format
msgid "Scale 100%"
msgstr "100% 比例"
#: app/adjustSizeButton.cpp:41
msgid "<b>Adjust video scale?"
msgstr "<b>调整视频比例?"
#: app/audioView.cpp:48 app/mainWindow.cpp:332
msgid "Show Analyzer"
msgstr "显示音频分析器"
#: app/captureFrame.cpp:92
#, c-format
msgid "Capture - %1"
msgstr "截图 - %1"
#: app/captureFrame.cpp:108
msgid ""
"*.png|PNG Format\n"
"*.jpeg|JPEG Format"
msgstr ""
"*.png|PNG图像格式\n"
"*.jpeg|JPEG图像格式"
#: app/captureFrame.cpp:110
msgid "Save Frame"
msgstr "保存一帧"
#: app/captureFrame.cpp:121
msgid "%1 saved successfully"
msgstr "%1 已保存"
#: app/captureFrame.cpp:123
#, c-format
msgid "Sorry, could not save %1"
msgstr "抱歉,无法保存 %1"
#: app/fullScreenAction.cpp:31
msgid "Exit F&ull Screen Mode"
msgstr "退出全屏模式"
#: app/fullScreenAction.cpp:37
msgid "F&ull Screen Mode"
msgstr "全屏模式(&F)"
#: app/insertAspectRatioMenuItems.cpp:16
msgid "Determine &Automatically"
msgstr "自动确认(&A)"
#: app/insertAspectRatioMenuItems.cpp:17
msgid "&Square (1:1)"
msgstr "方形 (1:1) (&S)"
#: app/insertAspectRatioMenuItems.cpp:18
msgid "&4:3"
msgstr "4:3(&4)"
#: app/insertAspectRatioMenuItems.cpp:19
msgid "Ana&morphic (16:9)"
msgstr "变形 (16:9) (&m)"
#: app/insertAspectRatioMenuItems.cpp:20
msgid "&DVB (2.11:1)"
msgstr "DVB (2.11:1) (&D)"
#: app/main.cpp:14
msgid "A video player that has a usability focus"
msgstr "注重可用性的视频播放器"
#: app/main.cpp:15
msgid "Copyright 2006, Max Howell"
msgstr "版权所有 2006, Max Howell"
#: app/main.cpp:20
msgid "Play 'URL'"
msgstr "播放 '链接'"
#: app/main.cpp:21
msgid "Play DVD Video"
msgstr "播放 DVD 视频"
#: app/main.cpp:31
msgid "Handbook"
msgstr "手册"
#: app/main.cpp:32
msgid "Great reference code"
msgstr "很好的参考代码"
#: app/main.cpp:33
msgid "The video for \"Call on Me\" encouraged plenty of debugging! ;)"
msgstr "这些视频在“叫我”要大量调试 ;)"
#: app/main.cpp:34
msgid "The current Codeine icon"
msgstr "当前的 Codeine 图标"
#: app/main.cpp:35
msgid "Patches, advice and moral support"
msgstr "bug 修补, 想法提供和支持"
#: app/mainWindow.cpp:143
msgid "Aspect Ratio"
msgstr "纵横比"
#: app/mainWindow.cpp:149
msgid "Audio Channels"
msgstr "音频轨道"
#: app/mainWindow.cpp:155
msgid "Subtitles"
msgstr "字幕"
#: app/mainWindow.cpp:277
msgid "Play &Media..."
msgstr "播放媒体(&M) ..."
#: app/mainWindow.cpp:283
msgid "Record"
msgstr "录制"
#: app/mainWindow.cpp:285
msgid "Reset Video Scale"
msgstr "重置视频比例"
#: app/mainWindow.cpp:286 app/mainWindow.cpp:650
msgid "Media Information"
msgstr "媒体信息"
#: app/mainWindow.cpp:287
msgid "Menu Toggle"
msgstr "切换菜单"
#: app/mainWindow.cpp:288
msgid "&Capture Frame"
msgstr "截图一帧(&C)"
#: app/mainWindow.cpp:290
msgid "Video Settings..."
msgstr "视频设置 ..."
#: app/mainWindow.cpp:291
msgid "Configure xine..."
msgstr "xine 引擎配置 ..."
#: app/mainWindow.cpp:293
msgid "Position Slider"
msgstr "滑块位置"
#: app/mainWindow.cpp:295
msgid "A&udio Channels"
msgstr "音频轨道(&u)"
#: app/mainWindow.cpp:298
msgid "&Subtitles"
msgstr "字幕(&S)"
#: app/mainWindow.cpp:301
msgid "Aspect &Ratio"
msgstr "宽高比(&R)"
#: app/mainWindow.cpp:425
msgid "Codeine was asked to open an empty URL; it cannot."
msgstr "Codeine 被要求打开一个空的 URL但实际上它做不到。"
#: app/mainWindow.cpp:487
msgid "Supported Media Formats"
msgstr "支持的媒体格式"
#: app/mainWindow.cpp:487
msgid "All Files"
msgstr "所有文件"
#: app/mainWindow.cpp:488
msgid "Select A File To Play"
msgstr "选择一个文件以播放"
#: app/mainWindow.cpp:714
msgid "Sorry, no media was found in the drop"
msgstr "抱歉,拖到窗口的媒体疑似不是媒体"
#: app/playDialog.cpp:28
msgid "Play Media"
msgstr "播放媒体"
#: app/playDialog.cpp:34
msgid "What media would you like to play?"
msgstr "你想要播放什么媒体?"
#: app/playDialog.cpp:39
msgid "Play File..."
msgstr "一些文件..."
#: app/playDialog.cpp:43
msgid "Play VCD"
msgstr "播放 VCD"
#: app/playDialog.cpp:47
msgid "Play DVD"
msgstr "播放 DVD"
#: app/playDialog.cpp:75
msgid "Recently Played Media"
msgstr "最近播放媒体"
#: app/playlistFile.cpp:32
msgid "The file is not a playlist"
msgstr "该文件不是一个播放列表"
#: app/playlistFile.cpp:39
#, c-format
msgid "Codeine could not download the remote playlist: %1"
msgstr "Codeine 播放器无法下载远程播放列表: %1"
#: app/playlistFile.cpp:54
msgid ""
"<qt>The playlist, <i>'%1'</i>, could not be interpreted. Perhaps it is empty?"
msgstr "<qt>播放列表 <i>'%1'</i> 无法解析。也许它是空的?"
#: app/playlistFile.cpp:58
#, c-format
msgid "Codeine could not open the file: %1"
msgstr "Codeine 无法打开该文件: %1"
#: app/stateChange.cpp:92
msgid "&Pause"
msgstr "暂停(&P)"
#: app/stateChange.cpp:92
msgid "&Play"
msgstr "播放(&P)"
#: app/stateChange.cpp:171
msgid "No media loaded"
msgstr "没有加载媒体文件"
#: app/stateChange.cpp:174
msgid "Paused"
msgstr "已暂停"
#: app/theStream.cpp:108
msgid "Metadata"
msgstr "元数据"
#: app/theStream.cpp:110
msgid "Title"
msgstr "标题"
#: app/theStream.cpp:111
msgid "Comment"
msgstr "注释"
#: app/theStream.cpp:112
msgid "Artist"
msgstr "艺术家"
#: app/theStream.cpp:113
msgid "Genre"
msgstr "分类"
#: app/theStream.cpp:114
msgid "Album"
msgstr "专辑"
#: app/theStream.cpp:115
msgid "Year"
msgstr "年份"
#: app/theStream.cpp:117
msgid "Audio Properties"
msgstr "音频属性"
#: app/theStream.cpp:119
msgid "Bitrate"
msgstr "比特率"
#: app/theStream.cpp:119
msgid "%1 bps"
msgstr "%1 BPS"
#: app/theStream.cpp:120
msgid "Sample-rate"
msgstr "采样率"
#: app/theStream.cpp:120
msgid "%1 Hz"
msgstr "%1 Hz"
#: app/theStream.cpp:122
msgid "Technical Information"
msgstr "技术信息"
#: app/theStream.cpp:124
msgid "Video Codec"
msgstr "视频编解码器"
#: app/theStream.cpp:125
msgid "Audio Codec"
msgstr "音频编解码器"
#: app/theStream.cpp:126
msgid "System Layer"
msgstr "系统布局"
#: app/theStream.cpp:127
msgid "Input Plugin"
msgstr "输入插件"
#: app/theStream.cpp:128
msgid "CDINDEX_DISCID"
msgstr "CDINDEX_DISCID"
#: app/videoSettings.cpp:92
msgid "Video Settings"
msgstr "视频设置"
#: app/videoWindow.cpp:136
msgid "Pause"
msgstr "暂停"
#: app/volumeAction.cpp:32
msgid "Toggle Mute"
msgstr ""
#: app/volumeAction.cpp:62 part/part.cpp:39
msgid "Mute"
msgstr "静音"
#: app/volumeAction.cpp:87
msgid "Volume"
msgstr "音量"
#: app/volumeAction.cpp:127
#, c-format
msgid "Volume %1"
msgstr "音量 %1"
#: app/xineConfig.cpp:46
msgid "Configure xine"
msgstr "xine 引擎设置"
#: app/xineConfig.cpp:68
msgid ""
"Xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)"
msgstr "Xine 的默认配置通常是合理的。但我们还是给你提供配置的可能性 ;-)"
#: app/xineEngine.cpp:147 part/xineEngine.cpp:50
msgid "xine was unable to initialize any video-drivers."
msgstr "xine 无法初始化任何视频驱动。"
#: app/xineEngine.cpp:149 part/xineEngine.cpp:48
msgid "xine was unable to initialize any audio-drivers."
msgstr "xine 无法初始化任何音频驱动。"
#: app/xineEngine.cpp:254
#, c-format
msgid "Loading media: %1"
msgstr "加载媒体: %1"
#: app/xineEngine.cpp:360
#, c-format
msgid "Recording to: %1"
msgstr "重新编码到: %1"
#: app/xineEngine.cpp:393
msgid "Playback paused"
msgstr "回放已暂停"
#: app/xineEngine.cpp:398
msgid "Playback resumed"
msgstr "回放继续"
#: app/xineEngine.cpp:411
#, c-format
msgid "There is no input plugin that can read: %1."
msgstr "这里没有可读取的输入插件: %1 。"
#: app/xineEngine.cpp:414
#, c-format
msgid "There is no demux plugin available for %1."
msgstr "这里没有可用于 %1 的解复用器插件。"
#: app/xineEngine.cpp:417
#, c-format
msgid "Demuxing failed for %1."
msgstr "解复用失败: %1。"
#: app/xineEngine.cpp:422
#, c-format
msgid "Internal error while attempting to play %1."
msgstr "尝试播放时发生内部错误 %1。"
#: app/xineEngine.cpp:748 app/xineEngine.cpp:756
#, c-format
msgid "Channel %1"
msgstr "轨道 %1"
#: app/xineEngine.cpp:855 part/xineEngine.cpp:289
msgid "The source is encrypted and can not be decrypted."
msgstr "播放原已经被加密且无法解密。"
#: app/xineEngine.cpp:857 part/xineEngine.cpp:291
msgid "The host is unknown for the URL: <i>%1</i>"
msgstr "未知的 URL 主机:<i>%1</i>"
#: app/xineEngine.cpp:859 part/xineEngine.cpp:293
msgid "The device name you specified seems invalid."
msgstr "您指定的设备名称无效。"
#: app/xineEngine.cpp:861 part/xineEngine.cpp:295
msgid "The network appears unreachable."
msgstr "网络似乎无法访问。"
#: app/xineEngine.cpp:863 part/xineEngine.cpp:297
msgid "Audio output unavailable; the device is busy."
msgstr "音频输出不可用; 设备正在忙碌中。"
#: app/xineEngine.cpp:865 part/xineEngine.cpp:299
msgid "The connection was refused for the URL: <i>%1</i>"
msgstr "URL 连接被重置: <i>%1</i>"
#: app/xineEngine.cpp:867 part/xineEngine.cpp:301
msgid "xine could not find the URL: <i>%1</i>"
msgstr "xine 无法找到该 URL: <i>%1</i>"
#: app/xineEngine.cpp:869 part/xineEngine.cpp:303
msgid "Access was denied for the URL: <i>%1</i>"
msgstr "URL 访问被拒绝: <i>%1</i>"
#: app/xineEngine.cpp:871 part/xineEngine.cpp:305
msgid "The source cannot be read for the URL: <i>%1</i>"
msgstr "URL 对应源无法读取: <i>%1</i>"
#: app/xineEngine.cpp:873 part/xineEngine.cpp:307
msgid "A problem occurred while loading a library or decoder."
msgstr "加载库或解码器时出现问题。"
#: app/xineEngine.cpp:900 part/xineEngine.cpp:334
msgid "Sorry, no additional information is available."
msgstr "抱歉,没有信息可用。"
#: part/xineEngine.cpp:166
msgid "The Codeine video player could not find an input plugin for '%1'."
msgstr "Codeine 视频播放器找不到 '%1' 对应的输入插件。"
#: part/xineEngine.cpp:169
msgid "The Codeine video player could not find a demux plugin for '%1'."
msgstr "Codeine 视频播放器无法找不到 '%1' 对应的解复用器插件。"
#: part/xineEngine.cpp:172
msgid ""
"The Codeine video player failed to demux '%1'; please check your xine "
"installation."
msgstr "Codeine 视频播放起无法复用 '%1'; 请检查 xine 安装。"
#: part/xineEngine.cpp:177
msgid ""
"The Codeine video player reports an internal error; please check your xine "
"installation."
msgstr "Codeine 视频播放器出现了内部错误; 请检查 xine 安装。"
Loading…
Cancel
Save