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/
5 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 #################

@ -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
@ -31,11 +35,6 @@ include( CheckCXXSourceCompiles )
include( TDEMacros )
##### set version number ########################
tde_set_project_version( )
##### setup install paths
include( TDESetupPaths )

@ -8,7 +8,7 @@
Playback finished message (amaroK statusbar code?)
Mouse move to show toolbar 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
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.
@ -35,4 +35,4 @@
ACTION
xine config dialog is modal
REACTION
none, at least yet, it is far easier to maintain modal dialogs
none, at least yet, it is far easier to maintain modal dialogs

@ -1,7 +1,7 @@
#define VERSION "@VERSION@"
// 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
significant byte first (like Motorola and SPARC, unlike Intel). */

@ -348,7 +348,7 @@ distribution. -->
<title>Credits and License</title>
<sect1 id="kapp">
<sect1 id="tdeApp">
<title>&codeine;</title>
<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>
Show help about options
.TP
\*(T<\fB\-\-help\-qt\fR\*(T>
\*(T<\fB\-\-help\-tqt\fR\*(T>
Show TQt specific options
.TP
\*(T<\fB\-\-help\-tde\fR\*(T>

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

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

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

@ -4,18 +4,107 @@
#include "analyzer.h"
#include "../codeine.h"
#include "../debug.h"
#include <math.h> //interpolate()
#include <cmath> //interpolate()
#include <tdeglobalsettings.h>
#include <tqevent.h> //event()
#include "xineEngine.h"
#include "fht.cpp"
template<class W>
Analyzer::Base<W>::Base( TQWidget *parent, uint timeout )
Analyzer::Base<W>::Base( TQWidget *parent, uint timeout, uint scopeSize )
: W( parent, "Analyzer" )
, 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
Analyzer::Base<W>::event( TQEvent *e )
{
@ -36,98 +125,521 @@ Analyzer::Base<W>::event( TQEvent *e )
}
Analyzer::Base2D::Base2D( TQWidget *parent, uint timeout )
: Base<TQWidget>( parent, timeout )
Analyzer::Base2D::Base2D( TQWidget *parent, uint timeout, uint scopeSize )
: Base<TQWidget>( parent, timeout, scopeSize )
{
setWFlags( TQt::WNoAutoErase ); //no flicker
connect( &m_timer, SIGNAL(timeout()), SLOT(draw()) );
connect( &m_timer, TQ_SIGNAL(timeout()), TQ_SLOT(draw()) );
}
void
Analyzer::Base2D::draw()
Analyzer::Base2D::resizeEvent( TQResizeEvent *e)
{
switch( Codeine::engine()->state() ) {
case Engine::Playing:
{
const Engine::Scope &thescope = Codeine::engine()->scope();
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 );
analyze( scope );
scope.resize( Analyzer::SCOPE_SIZE );
bitBlt( this, 0, 0, canvas() );
break;
}
case Engine::Paused:
break;
m_background.resize(size());
m_canvas.resize(size());
m_background.fill(backgroundColor());
eraseCanvas();
default:
erase();
}
TQWidget::resizeEvent(e);
}
void
Analyzer::Base2D::resizeEvent( TQResizeEvent* )
void Analyzer::Base2D::paletteChange(const TQPalette&)
{
m_canvas.resize( size() );
m_canvas.fill( colorGroup().background() );
m_background.fill(backgroundColor());
eraseCanvas();
}
// Author: Max Howell <max.howell@methylblue.com>, (C) 2003
// Copyright: See COPYING file that comes with this distribution
#include <tqpainter.h>
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
setMaximumWidth( 128 );
// -1 is padding, no drawing takes place there
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
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 )
scope[x] *= 2;
float *front = static_cast<float*>( &s.front() );
float *front = static_cast<float*>( &scope.front() );
m_fht->spectrum( front );
m_fht->scale( front, 1.0 / 20 );
fht.spectrum( front );
fht.scale( front, 1.0 / 40 );
//the second half is pretty dull, so only show it if the user has a large analyzer
//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
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));
}
TQPainter p( canvas() );
p.setPen( colorGroup().background() );
for (unsigned x = 0; x < m_store.size(); ++x)
{
bitBlt(canvas(), x * (WIDTH + 1), int(m_store[x]) * (HEIGHT + 1) + m_y, &m_topBarPixmap);
}
}
const double F = double(height()) / (log10( 256 ) * 1.1 /*<- max. amplitude*/);
for( uint x = 0; x < s.size(); ++x )
//we draw the blank bit
p.drawLine( x, 0, x, int(height() - log10( s[x] * 256.0 ) * F) );
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;
}
}
}
int
Analyzer::Block::heightForWidth( int w ) const
/**
* 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)
{
return w / 2;
class OutputOnExit
{
public:
explicit OutputOnExit(const TQColor &color)
: c(color)
{
}
~OutputOnExit()
{
int h, s, v;
c.getHsv(&h, &s, &v);
}
private:
const TQColor &c;
};
// hack so I don't have to cast everywhere
#define amount static_cast<int>(_amount)
// #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;
}
void Analyzer::Block::drawBackground()
{
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"

@ -8,6 +8,7 @@
#include <sys/types.h>
#endif
#include "fht.h"
#include <tqpixmap.h> //stack allocated and convenience
#include <tqtimer.h> //stack allocated
#include <tqwidget.h> //baseclass
@ -23,10 +24,13 @@ namespace Analyzer
uint timeout() const { return m_timeout; }
protected:
Base( TQWidget*, uint );
Base( TQWidget*, uint, uint = 7 );
~Base() { delete m_fht; }
void drawFrame();
virtual void transform( Scope& ) = 0;
virtual void analyze( const Scope& ) = 0;
virtual void demo();
private:
virtual bool event( TQEvent* );
@ -34,42 +38,91 @@ namespace Analyzer
protected:
TQTimer m_timer;
uint m_timeout;
FHT *m_fht;
};
class Base2D : public Base<TQWidget>
{
Q_OBJECT
TQ_OBJECT
public:
const TQPixmap *background() const { return &m_background; }
const TQPixmap *canvas() const { return &m_canvas; }
private slots:
void draw();
void draw() { drawFrame(); bitBlt(this, 0, 0, canvas()); }
protected:
Base2D( TQWidget*, uint timeout );
Base2D( TQWidget*, uint timeout, uint scopeSize = 7 );
TQPixmap *background() { return &m_background; }
TQPixmap *canvas() { return &m_canvas; }
void paintEvent( TQPaintEvent* ) { if( !m_canvas.isNull() ) bitBlt( this, 0, 0, canvas() ); }
void resizeEvent( TQResizeEvent* );
void eraseCanvas()
{
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:
TQPixmap m_background;
TQPixmap m_canvas;
};
class Block : public Analyzer::Base2D
{
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:
virtual void transform( 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;
}
virtual int heightForWidth( int ) const;
// So we don't create a vector each frame.
Scope m_scope;
TQPixmap m_barPixmap;
TQPixmap m_topBarPixmap;
virtual void show() {} //TODO temporary as the scope plugin causes freezes
// Current bar heights
std::vector<float> m_store;
std::vector<float> m_yScale;
std::vector<TQPixmap> m_fadeBars;
std::vector<int> m_fadeIntensity;
std::vector<unsigned> m_fadePos;
// 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

@ -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 <kstatusbar.h>
#include <kstdguiitem.h>
#include <tqapplication.h>
#include <tqdialog.h>
#include <tqhbox.h>
#include <tqlabel.h>
@ -69,15 +70,24 @@ public:
, m_title( TheStream::prettyTitle() )
{
(new TQVBoxLayout( this ))->setAutoAdd( true );
(new TQLabel( this ))->setPixmap( frame );
// 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 );
} else {
TQSize scaledSize = screenRect.size() * 0.9;
TQImage scaledImage = frame.scale( scaledSize, TQImage::ScaleMin );
(new TQLabel( this ))->setPixmap( scaledImage );
}
TQHBox *box = new TQHBox( this );
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->setText( i18n("Discard") );
connect( o, SIGNAL(clicked()), SLOT(reject()) );
connect( o, TQ_SIGNAL(clicked()), TQ_SLOT(reject()) );
setCaption( i18n("Capture - %1").arg( time ) );
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_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 )
return 0;
@ -241,28 +251,34 @@ VideoWindow::captureFrame() const
DEBUG_BLOCK
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();
uint8_t *yuv = new uint8_t[((w+8) * (h+1) * 2)];
if( yuv == 0 ) {
int yuv_size = ((w + 8) * (h + 1)) * 2;
uint8_t *yuv = new(std::nothrow) uint8_t[yuv_size];
if (yuv == nullptr) {
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
uint8_t *y = 0, *u = 0, *v = 0;
uint8_t *y = nullptr;
uint8_t *u = nullptr;
uint8_t *v = nullptr;
switch( format )
{
case XINE_IMGFMT_YUY2: {
uint8_t *yuy2 = yuv;
yuv = new uint8_t[(w * h * 2)];
if( yuv == 0 ) {
yuv = new(std::nothrow) uint8_t[(w * h * 2)];
if (yuv == nullptr) {
Debug::error() << "Not enough memory to make screenframe!\n";
delete [] yuy2;
return TQImage(); }
return TQImage();
}
y = yuv;
u = yuv + w * h;
@ -287,7 +303,7 @@ VideoWindow::captureFrame() const
// convert to rgb
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;
return frame;

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

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

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

@ -11,6 +11,7 @@
#include <kcursor.h>
#include <tdefiledialog.h> //::open()
#include <tdeglobalsettings.h> //::timerEvent()
#include <tdepopupmenu.h>
#include <tdeio/netaccess.h>
#include <ksqueezedtextlabel.h>
#include <kstatusbar.h>
@ -18,16 +19,17 @@
#include <kurldrag.h>
#include <twin.h>
#include <tqcstring.h>
#include <tqdesktopwidget.h>
#include <tqevent.h> //::stateChanged()
#include <tqlayout.h> //ctor
#include <tqpopupmenu.h> //because XMLGUI is poorly designed
#include <tqobjectlist.h>
#include <tqwidgetstack.h>
#include "../debug.h"
#include "../mxcl.library.h"
#include "actions.h"
#include "analyzer.h"
#include "audioView.h"
#include "codeineConfig.h"
#include "extern.h" //dialog creation function definitions
#include "fullScreenAction.h"
@ -48,12 +50,15 @@ extern "C"
}
#endif
constexpr auto kAspectSelectActionName = "aspect_ratio_select";
constexpr auto kAudioSelectActionName = "audio_channels_select";
constexpr auto kSubtitleSelectActionName = "subtitle_channels_select";
namespace Codeine {
/// @see codeine.h
TQWidget *mainWindow() { return kapp->mainWidget(); }
TQWidget *mainWindow() { return tdeApp->mainWidget(); }
MainWindow::MainWindow()
@ -66,10 +71,21 @@ MainWindow::MainWindow()
clearWFlags( WDestructiveClose ); //we are allocated on the stack
kapp->setMainWidget( this );
tdeApp->setMainWidget( this );
m_widgetStack = new TQWidgetStack(this, "m_widgetStack");
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
// these have no affect beccause "KDE Knows Best" FFS
@ -93,6 +109,9 @@ MainWindow::MainWindow()
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!
m_showAnalyzer = config("MainWindow")->readBoolEntry("showAnalyzer", true);
m_analyzer->setShown(m_showAnalyzer);
// only show dvd button when playing a dvd
{
struct KdeIsTehSuck : public TQObject
@ -116,26 +135,27 @@ MainWindow::MainWindow()
}
{
TQPopupMenu *menu = 0, *settings = static_cast<TQPopupMenu*>(factory()->container( "settings", this ));
int id = SubtitleChannelsMenuItemId, index = 0;
#define make_menu( name, text ) \
menu = new TQPopupMenu( this, name ); \
menu->setCheckable( true ); \
connect( menu, SIGNAL(activated( int )), engine(), SLOT(setStreamParameter( int )) ); \
connect( menu, SIGNAL(aboutToShow()), SLOT(aboutToShowMenu()) ); \
settings->insertItem( text, menu, id, index ); \
settings->setItemEnabled( id, false ); \
id++, index++;
make_menu( "subtitle_channels_menu", i18n( "&Subtitles" ) );
make_menu( "audio_channels_menu", i18n( "A&udio Channels" ) );
make_menu( "aspect_ratio_menu", i18n( "Aspect &Ratio" ) );
#undef make_menu
Codeine::insertAspectRatioMenuItems( menu ); //so we don't have to include xine.h here
settings->insertSeparator( index );
/* Disable aspect/channel menus until the stream has loaded;
* Make sure they have the same default item selected. */
TQStringList defaultItems("&Determine Automatically");
if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action(kAspectSelectActionName)))
{
aspectAction->setToolTip(i18n("Aspect Ratio"));
insertAspectRatioMenuItems(aspectAction);
aspectAction->setEnabled(false);
}
if (const auto audioChannelAction = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
{
audioChannelAction->setToolTip(i18n("Audio Channels"));
audioChannelAction->setItems(defaultItems);
audioChannelAction->setEnabled(false);
}
if (const auto subChannelAction = dynamic_cast<TDESelectAction *>(action(kSubtitleSelectActionName)))
{
subChannelAction->setToolTip(i18n("Subtitles"));
subChannelAction->setItems(defaultItems);
subChannelAction->setEnabled(false);
}
}
TQObjectList *list = toolBar()->queryList( "TDEToolBarButton" );
@ -153,13 +173,13 @@ MainWindow::MainWindow()
KXMLGUIClient::stateChanged( "empty" );
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
init();
else {
//"faster" startup
//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() ); }
}
@ -168,11 +188,15 @@ MainWindow::init()
{
DEBUG_BLOCK
connect( engine(), SIGNAL(statusMessage( const TQString& )), this, SLOT(engineMessage( const TQString& )) );
connect( engine(), SIGNAL(stateChanged( Engine::State )), this, SLOT(engineStateChanged( Engine::State )) );
connect( engine(), SIGNAL(channelsChanged( const TQStringList& )), this, SLOT(setChannels( const TQStringList& )) );
connect( engine(), SIGNAL(titleChanged( const TQString& )), m_titleLabel, SLOT(setText( const TQString& )) );
connect( m_positionSlider, SIGNAL(valueChanged( int )), this, SLOT(showTime( int )) );
connect( engine(), TQ_SIGNAL(statusMessage( const TQString& )), this, TQ_SLOT(engineMessage( const TQString& )) );
connect( engine(), TQ_SIGNAL(stateChanged( Engine::State )), this, TQ_SLOT(engineStateChanged( Engine::State )) );
connect( engine(), TQ_SIGNAL(titleChanged( const TQString& )), m_titleLabel, TQ_SLOT(setText( const TQString& )) );
connect( m_positionSlider, TQ_SIGNAL(valueChanged( int )), this, TQ_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() ) {
KMessageBox::error( this, i18n(
@ -183,12 +207,12 @@ MainWindow::init()
//would be dangerous for these to65535 happen before the videoWindow() is initialised
setAcceptDrops( true );
connect( m_positionSlider, SIGNAL(sliderReleased( uint )), engine(), SLOT(seek( uint )) );
connect( statusBar(), SIGNAL(messageChanged( const TQString& )), engine(), SLOT(showOSD( const TQString& )) );
connect( m_positionSlider, TQ_SIGNAL(sliderReleased( uint )), engine(), TQ_SLOT(seek( uint )) );
connect( statusBar(), TQ_SIGNAL(messageChanged( const TQString& )), engine(), TQ_SLOT(showOSD( const TQString& )) );
TQApplication::restoreOverrideCursor();
if( !kapp->isRestored() ) {
if( !tdeApp->isRestored() ) {
TDECmdLineArgs &args = *TDECmdLineArgs::parsedArgs();
if (args.isSet( "play-dvd" ))
open( "dvd:/" );
@ -221,6 +245,9 @@ MainWindow::~MainWindow()
bool
MainWindow::queryExit()
{
config("MainWindow")->writeEntry("showAnalyzer", m_showAnalyzer);
config("MainWindow")->sync();
if( toggleAction( "fullscreen" )->isChecked() ) {
// there seems to be no other way to stop TDEMainWindow
// saving the window state without any controls
@ -246,26 +273,35 @@ MainWindow::setupActions()
TDEActionCollection * const ac = actionCollection();
KStdAction::quit( kapp, SLOT(quit()), ac );
KStdAction::open( this, SLOT(playMedia()), ac, "play_media" )->setText( i18n("Play &Media...") );
connect( new FullScreenAction( this, ac ), SIGNAL(toggled( bool )), SLOT(fullScreenToggled( bool )) );
KStdAction::quit( tdeApp, TQ_SLOT(quit()), ac );
KStdAction::open( this, TQ_SLOT(playMedia()), ac, "play_media" )->setText( i18n("Play &Media...") );
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("Stop"), "media-playback-stop", Key_S, engine(), SLOT(stop()), ac, "stop" );
new TDEAction( i18n("Video Settings..."), "configure", Key_V, this, TQ_SLOT(configure()), ac, "video_settings" );
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" );
new TDEAction( i18n("Media Information"), "messagebox_info", Key_I, this, SLOT(streamInformation()), ac, "information" );
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" );
const auto audioSelectAction = new TDESelectAction(i18n("A&udio Channels"), 0, ac, kAudioSelectActionName);
connect(audioSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
new TDEAction( i18n("Video Settings..."), "configure", Key_V, this, SLOT(configure()), ac, "video_settings" );
new TDEAction( i18n("Configure xine..."), "configure", 0, this, SLOT(configure()), ac, "xine_settings" );
const auto subSelectAction = new TDESelectAction(i18n("&Subtitles"), 0, ac, kSubtitleSelectActionName);
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
@ -282,6 +318,24 @@ MainWindow::readProperties( TDEConfig *config )
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
MainWindow::timerEvent( TQTimerEvent* )
{
@ -331,6 +385,13 @@ MainWindow::showTime( int pos )
m_timeLabel->setText( time );
}
void
MainWindow::toggleAnalyzer()
{
m_showAnalyzer = !m_showAnalyzer;
m_analyzer->setShown(m_showAnalyzer);
}
void
MainWindow::engineMessage( const TQString &message )
{
@ -381,7 +442,7 @@ MainWindow::load( const KURL &url )
if (url.protocol() == "media") {
#define UDS_LOCAL_PATH (72 | TDEIO::UDS_STRING)
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..." );
else {
TDEIO::UDSEntry::ConstIterator end = e.end();
@ -507,7 +568,6 @@ show_toolbar:
//we aren't managed by mainWindow when at FullScreen
videoWindow()->move( 0, 0 );
videoWindow()->resize( ((TQWidget*)o)->size() );
videoWindow()->lower();
}
if (o == m_toolbar)
@ -564,14 +624,12 @@ MainWindow::fullScreenToggled( bool isFullScreen )
statusBar()->setHidden( isFullScreen );
setMouseTracking( isFullScreen ); /// @see mouseMoveEvent()
m_widgetStack->setMouseTracking(isFullScreen);
if (isFullScreen)
s_handler = new FullScreenToolBarHandler( this );
else
delete s_handler;
// prevent videoWindow() moving around when mouse moves
setCentralWidget( isFullScreen ? 0 : videoWindow() );
}
void
@ -593,54 +651,49 @@ MainWindow::streamInformation()
}
void
MainWindow::setChannels( const TQStringList &channels )
MainWindow::setAudioChannels(const TQStringList &channels) const
{
DEBUG_FUNC_INFO
//TODO -1 = auto
TQStringList::ConstIterator it = channels.begin();
TQPopupMenu *menu = (TQPopupMenu*)child( (*it).latin1() );
menu->clear();
/* 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. */
menu->insertItem( i18n("&Determine Automatically"), 1 );
menu->insertSeparator();
//the id is crucial, since the slot this menu is connected to requires
//that information to set the correct channel
//NOTE we subtract 2 in xineEngine because TQMenuData doesn't allow negative id
int id = 2;
++it;
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 );
if (const auto audioSelection = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
{
TQStringList audioChannels(channels);
audioChannels.prepend("&Determine Automatically");
audioChannels.prepend("&Off");
audioSelection->setItems(audioChannels);
audioSelection->popupMenu()->insertSeparator(2);
audioSelection->setCurrentItem(TheStream::audioChannel() + 2);
audioSelection->setEnabled(channels.count());
}
else
{
Debug::error() << "Failed to update the audio channels (selection menu not found)" << endl;
}
}
void
MainWindow::aboutToShowMenu()
MainWindow::setSubtitleChannels(const TQStringList &channels) const
{
TQPopupMenu *menu = (TQPopupMenu*)sender();
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();
DEBUG_FUNC_INFO
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
@ -681,10 +734,10 @@ MainWindow::keyPressEvent( TQKeyEvent *e )
}
TQPopupMenu*
MainWindow::menu( const char *name )
MainWindow::menu( const TQString& name )
{
// 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*
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
@ -701,17 +754,23 @@ action( const char *name )
{
#define QT_FATAL_ASSERT
MainWindow *mainWindow = 0;
TDEActionCollection *actionCollection = 0;
TDEAction *action = 0;
MainWindow *mainWindow = nullptr;
TDEActionCollection *actionCollection = nullptr;
TDEAction *action = nullptr;
if( mainWindow = (MainWindow*)kapp->mainWidget() )
if( actionCollection = mainWindow->actionCollection() )
action = actionCollection->action( name );
mainWindow = dynamic_cast<MainWindow *>(tdeApp->mainWidget());
if (mainWindow)
{
actionCollection = mainWindow->actionCollection();
if (actionCollection)
{
action = actionCollection->action(name);
}
}
Q_ASSERT( mainWindow );
Q_ASSERT( actionCollection );
Q_ASSERT( action );
Q_ASSERT(mainWindow);
Q_ASSERT(actionCollection);
Q_ASSERT(action);
return action;
}

@ -11,13 +11,17 @@ class KURL;
class TQLabel;
class TQPopupMenu;
class TQSlider;
class TQWidgetStack;
class VolumeAction;
namespace Codeine
{
class AudioView;
class MainWindow : public TDEMainWindow
{
Q_OBJECT
TQ_OBJECT
MainWindow();
~MainWindow();
@ -39,9 +43,10 @@ namespace Codeine
void engineStateChanged( Engine::State );
void init();
void showTime( int = -1 );
void setChannels( const TQStringList& );
void aboutToShowMenu();
void fullScreenToggled( bool );
void setAudioChannels(const TQStringList&) const;
void setSubtitleChannels(const TQStringList&) const;
void toggleAnalyzer();
private:
void setupActions();
@ -49,8 +54,9 @@ namespace Codeine
bool load( 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 dragEnterEvent( TQDragEnterEvent* );
virtual void dropEvent( TQDropEvent* );
@ -65,6 +71,13 @@ namespace Codeine
TQLabel *m_timeLabel;
TQLabel *m_titleLabel;
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
MainWindow( const MainWindow& );

@ -25,7 +25,7 @@ namespace Codeine {
PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog )
: TQDialog( parent )
{
setCaption( kapp->makeStdCaption( i18n("Play Media") ) );
setCaption( tdeApp->makeStdCaption( i18n("Play Media") ) );
TQSignalMapper *mapper = new TQSignalMapper( 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
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 );
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 );
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 );
mapper->setMapping( closeButton, TQDialog::Rejected );
connect( closeButton, SIGNAL(clicked()), mapper, SLOT(map()) );
connect( closeButton, TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()) );
createRecentFileWidget( vbox );
@ -59,12 +59,12 @@ PlayDialog::PlayDialog( TQWidget *parent, bool be_welcome_dialog )
if( be_welcome_dialog ) {
TQWidget *w = new KPushButton( KStdGuiItem::quit(), this );
hbox->addWidget( w );
connect( w, SIGNAL(clicked()), kapp, SLOT(quit()) );
connect( w, TQ_SIGNAL(clicked()), tdeApp, TQ_SLOT(quit()) );
}
hbox->addWidget( closeButton );
connect( mapper, SIGNAL(mapped( int )), SLOT(done( int )) );
connect( mapper, TQ_SIGNAL(mapped( int )), TQ_SLOT(done( int )) );
}
void
@ -93,12 +93,12 @@ PlayDialog::createRecentFileWidget( TQBoxLayout *layout )
for( KURL::List::ConstIterator it = urls.begin(), end = urls.end(); it != end; ++it ) {
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() ) {
layout->addWidget( lv, 1 );
connect( lv, SIGNAL(executed( TQListViewItem* )), SLOT(done( TQListViewItem* )) );
connect( lv, TQ_SIGNAL(executed( TQListViewItem* )), TQ_SLOT(done( TQListViewItem* )) );
}
else
delete lv;

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

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

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

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

@ -37,7 +37,7 @@ public:
setTickmarks( TQSlider::Below );
setTickInterval( 65536 / 4 );
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 )

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

@ -1,12 +1,15 @@
// (C) 2005 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdetoolbar.h>
#include <tqevent.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqslider.h>
#include <tqtoolbutton.h>
#include <tqtooltip.h>
#include "../debug.h"
#include "volumeAction.h"
@ -20,37 +23,77 @@ public:
VolumeSlider( TQWidget *parent )
: TQFrame( parent )
{
slider = new TQSlider( TQt::Vertical, this, "volume" );
label = new TQLabel( this );
slider = new TQSlider(TQt::Vertical, this, "volume");
label = new TQLabel(this);
TQBoxLayout *lay = new TQVBoxLayout( this );
lay->addWidget( slider, 0, TQt::AlignHCenter );
lay->addWidget( label, 0, TQt::AlignHCenter );
lay->setMargin( 4 );
mute = new TQToolButton(this, "volume_slider_mute");
mute->setAutoRaise(true);
mute->setToggleButton(true);
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 );
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();
}
TQToolButton *mute;
TQLabel *label;
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 )
: TDEToggleAction( i18n("Volume"), "volume", TQt::Key_1, 0, 0, ac, "volume" )
, m_anchor( 0 )
: TDEToggleAction( i18n("Volume"), "volume", TQt::Key_1, nullptr, nullptr, ac, "volume" )
, m_anchor( nullptr )
{
m_widget = new VolumeSlider( bar->topLevelWidget() );
connect( this, SIGNAL(toggled( bool )), SLOT(toggled( bool )) );
connect( m_widget->slider, SIGNAL(sliderMoved( int )), SLOT(sliderMoved( int )) );
connect( m_widget->slider, SIGNAL(sliderMoved( int )), Codeine::engine(), SLOT(setStreamParameter( int )) );
connect( m_widget->slider, SIGNAL(sliderReleased()), SLOT(sliderReleased()) );
connect(this, TQ_SIGNAL(toggled(bool)), TQ_SLOT(toggled(bool)));
connect(m_widget->mute, TQ_SIGNAL(toggled(bool)), Codeine::engine(), TQ_SLOT(setMuted(bool)));
connect(m_widget->mute, TQ_SIGNAL(toggled(bool)), TQ_SLOT(setMuted(bool)));
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
@ -69,21 +112,32 @@ VolumeAction::plug( TQWidget *bar, int index )
void
VolumeAction::toggled( bool const b )
{
DEBUG_BLOCK
m_widget->raise();
m_widget->setShown( b );
}
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 ) );
m_widget->label->setText( t );
void
VolumeAction::setVolume(int volume)
{
// TQt sliders are the wrong way round when vertical.
m_widget->slider->setValue(100 - volume);
}
bool
@ -94,8 +148,8 @@ VolumeAction::eventFilter( TQObject *o, TQEvent *e )
case TQEvent::Resize: {
TQWidget const * const &a = m_anchor;
m_widget->move( a->mapTo( m_widget->parentWidget(), TQPoint( 0, a->height() ) ) );
m_widget->resize( a->width(), m_widget->sizeHint().height() );
m_widget->resize( m_widget->requiredWidth, m_widget->sizeHint().height() );
m_widget->move( a->mapTo( m_widget->parentWidget(), TQPoint( a->width() - m_widget->width(), a->height() ) ) );
return false;
}

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

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

@ -25,18 +25,20 @@
namespace Codeine {
VideoWindow *VideoWindow::s_instance = 0;
VideoWindow *VideoWindow::s_instance = nullptr;
bool VideoWindow::s_logarithmicVolume = false;
VideoWindow::VideoWindow( TQWidget *parent )
: TQWidget( parent, "VideoWindow" )
, m_osd( 0 )
, m_stream( 0 )
, m_eventQueue( 0 )
, m_videoPort( 0 )
, m_audioPort( 0 )
, m_scope( 0 )
, m_xine( 0 )
, m_osd( nullptr )
, m_stream( nullptr )
, m_eventQueue( nullptr )
, m_videoPort( nullptr )
, m_audioPort( nullptr )
, m_post( nullptr )
, m_xine( nullptr )
, m_scope( Analyzer::SCOPE_SIZE * 2 ) // Multiply by two to account for interleaved PCM.
, m_current_vpts( 0 )
{
DEBUG_BLOCK
@ -50,9 +52,12 @@ VideoWindow::VideoWindow( TQWidget *parent )
setPaletteBackgroundColor( TQt::black );
setFocusPolicy( ClickFocus );
//TODO sucks
//TODO namespace this?
myList->next = myList; //init the buffer list
// Detect xine version, this is used for volume adjustment.
// Xine versions prior to 1.2.13 use linear volume, so the engine uses logarithmic volume.
// 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()
@ -65,7 +70,12 @@ VideoWindow::~VideoWindow()
if( m_stream && xine_get_status( m_stream ) == XINE_STATUS_PLAY ) {
int cum = 0;
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));
::usleep( sleep );
@ -88,7 +98,7 @@ VideoWindow::~VideoWindow()
if( m_stream ) xine_dispose( m_stream );
if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort );
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 );
cleanUpVideo();
@ -106,7 +116,7 @@ VideoWindow::init()
if( !m_xine )
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";
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() );
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";
m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort );
@ -148,9 +158,9 @@ VideoWindow::init()
debug() << "scope_plugin_new()\n";
#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)
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
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
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_AUDIO_CHANNEL_LOGICAL, -1 );
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 );
#undef setParameter
@ -265,11 +276,11 @@ VideoWindow::load( const KURL &url )
// ensure old buffers are deleted
// 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_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 );
}
@ -359,6 +370,8 @@ VideoWindow::stop()
{
xine_stop( m_stream );
std::fill(m_scope.begin(), m_scope.end(), 0);
announceStateChange();
}
@ -442,11 +455,29 @@ VideoWindow::posTimeLength( PosTimeLength type ) const
return 0; //--warning
}
bool
VideoWindow::isMuted() const
{
return xine_get_param(m_stream, XINE_PARAM_AUDIO_AMP_MUTE);
}
uint
VideoWindow::volume() const
{
//TODO I don't like the design
return xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL );
int vol = 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
@ -492,12 +523,6 @@ VideoWindow::seek( uint pos )
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
//NOTE doesn't work! I can't tell why..
Slider::instance()->TQSlider::setValue( pos );
@ -532,6 +557,13 @@ VideoWindow::seek( uint pos )
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
VideoWindow::setStreamParameter( int value )
{
@ -546,39 +578,61 @@ VideoWindow::setStreamParameter( int value )
parameter = XINE_PARAM_VO_CONTRAST;
else if( sender == "brightness" )
parameter = XINE_PARAM_VO_BRIGHTNESS;
else if( sender == "subtitle_channels_menu" )
else if( sender == "subtitle_channels_select" )
parameter = XINE_PARAM_SPU_CHANNEL,
value -= 2;
else if( sender == "audio_channels_menu" )
else if( sender == "audio_channels_select" )
parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
value -= 2;
else if( sender == "aspect_ratio_menu" )
else if( sender == "aspect_ratio_select" )
parameter = XINE_PARAM_VO_ASPECT_RATIO;
else if( sender == "volume" )
{
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
return;
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&
VideoWindow::scope()
{
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;
}
if( xine_get_status( m_stream ) != XINE_STATUS_PLAY )
return 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 (channels > 2)
{
return m_scope;
}
//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 channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_CHANNELS ), frame = 0; frame < SCOPE_SIZE; )
for (int n, frame = 0; frame < SCOPE_SIZE; /* no-op */)
{
MyNode *best_node = 0;
MyNode *best_node = nullptr;
for( MyNode *node = myList->next; node != myList; node = node->next )
if( node->vpts <= m_current_vpts && (!best_node || node->vpts > best_node->vpts) )
@ -597,10 +651,10 @@ VideoWindow::scope()
data16 = best_node->mem;
data16 += diff;
diff += diff % channels; //important correction to ensure we don't overflow the buffer
diff /= channels;
diff += diff % channels; // important correction to ensure we don't overflow the buffer.
diff /= channels; // use units of frames, not samples.
int
// calculate the number of available samples in this buffer.
n = best_node->num_frames;
n -= diff;
n += frame; //clipping for # of frames we need
@ -610,33 +664,52 @@ VideoWindow::scope()
for( int a, c; frame < n; ++frame, data16 += channels ) {
for( a = c = 0; c < channels; ++c )
a += data16[c];
a /= channels;
scope[frame] = a;
{
// now we give interleaved PCM to the scope.
m_scope[scopeIdx++] = data16[c];
if (channels == 1)
{
// Duplicate mono samples.
m_scope[scopeIdx++] = data16[c];
}
}
}
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
}
return scope;
return m_scope;
}
void
VideoWindow::timerEvent( TQTimerEvent* )
{
if (!m_stream)
{
return;
}
/// here we prune the buffer list regularly
MyNode * const first_node = myList->next;
MyNode const * const list_end = myList;
MyNode *myList = scope_plugin_list(m_post);
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)
? xine_get_current_vpts( m_stream )
: 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
if( node->vpts_end < m_current_vpts ) {
prev->next = node->next;
@ -669,19 +742,19 @@ VideoWindow::customEvent( TQCustomEvent *e )
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 );
for( int j = 0; j < channels; j++ )
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 );
for( int j = 0; j < channels; j++ )
languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 );
emit channelsChanged( languages );
emit audioChannelsChanged(languages);
}
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
debug() << "XINE_EVENT_MRL_REFERENCE\n";
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;
}
case XINE_EVENT_DROPPED_FRAMES: debug() << "XINE_EVENT_DROPPED_FRAMES\n"; break;
@ -840,7 +913,7 @@ VideoWindow::toggleDVDMenu()
{
xine_event_t e;
e.type = XINE_EVENT_INPUT_MENU1;
e.data = NULL;
e.data = nullptr;
e.data_length = 0;
xine_event_send( m_stream, &e );
@ -862,13 +935,37 @@ VideoWindow::fileFilter() const
{
char *supportedExtensions = xine_get_file_extensions( m_xine );
TQString filter( "*." );
filter.append( supportedExtensions );
filter.remove( "txt" );
filter.remove( "png" );
filter.replace( ' ', " *." );
std::free( supportedExtensions );
TQString filter("*.");
filter.append(supportedExtensions);
// Remove protocols
filter.remove(" dvb://");
filter.remove(" dvbc://");
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;
}

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

@ -4,16 +4,38 @@
/* need access to port_ticket */
#define XINE_ENGINE_INTERNAL
#define LOG_MODULE "codine-scope"
#define LOG_LEVEL LOG_LEVEL_DEBUG
// #define LOG
#include "xineScope.h"
#include <xine/post.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;
static int myChannels = 0;
static int64_t pts_per_smpls;
int scope_plugin_channels(void *post)
{
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 *
@ -22,7 +44,10 @@ MyNode* const myList = &theList;
static int
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;
scope_plugin_t *self = (scope_plugin_t *)port->post;
_x_post_rewire( (post_plugin_t*)port->post );
_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->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 );
#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)
pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate;
self->pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate;
#else
pts_per_smpls = stream->metronom->pts_per_smpls;
self->pts_per_smpls = stream->metronom->pts_per_smpls;
#endif
return ret;
}
@ -47,7 +72,17 @@ scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bi
static void
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;
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->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 )
{
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 */
/* 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; }
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) );
#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
K = pts_per_smpls; /*smpls = 1<<16 samples*/
K = self->pts_per_smpls; /*smpls = 1<<16 samples*/
K *= num_samples;
K /= (1<<16);
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
* NOTE this is thread-safe due to the way we handle the list in the GUI thread */
new_node->next = myList->next;
myList->next = new_node;
new_node->next = self->list->next;
self->list->next = new_node;
}
static void
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 )
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_out_t *output;
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) || \
(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.put_buffer = scope_port_put_buffer;
this->xine_post.audio_input[0] = &port->new_port;
this->xine_post.type = PLUGIN_POST;
post_plugin->xine_post.audio_input[0] = &port->new_port;
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) || \
@ -153,6 +204,12 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
post_plugin->xine = xine;
#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) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
return post_plugin;
@ -161,11 +218,6 @@ xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target )
#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) || \
(XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10)
static void *scope_init_plugin(xine_t *xine, const void *data)

@ -33,18 +33,23 @@ struct my_node_s
int64_t vpts_end;
};
extern MyNode* const myList;
#ifdef __cplusplus
extern "C"
{
#endif
#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)
extern const plugin_info_t scope_plugin_info[];
#else
xine_post_t* scope_plugin_new( xine_t*, xine_audio_port_t* );
#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

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

@ -35,8 +35,8 @@ namespace Codeine
//FIXME this will terminate the host, eg Konqueror
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 *mute = new TDEToggleAction( i18n("Mute"), "player_mute", TQt::Key_M, videoWindow(), SLOT(toggleMute()), actionCollection(), "mute" );
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(), TQ_SLOT(toggleMute()), actionCollection(), "mute" );
TDEToolBar *toolBar = new MouseOverToolBar( widget() );
play->plug( toolBar );
mute->plug( toolBar );
@ -46,8 +46,8 @@ namespace Codeine
toolBar->addSeparator(); //FIXME ugly
TQObject *o = (TQObject*)statusBar();
connect( videoWindow(), SIGNAL(statusMessage( const TQString& )), o, SLOT(message( const TQString& )) );
connect( videoWindow(), SIGNAL(titleChanged( const TQString& )), o, SLOT(message( const TQString& )) ); //FIXME
connect( videoWindow(), TQ_SIGNAL(statusMessage( const TQString& )), o, TQ_SLOT(message( const TQString& )) );
connect( videoWindow(), TQ_SIGNAL(titleChanged( const TQString& )), o, TQ_SLOT(message( const TQString& )) ); //FIXME
}
bool

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

@ -24,7 +24,7 @@ namespace Codeine
{
class VideoWindow : public TQWidget
{
Q_OBJECT
TQ_OBJECT
static VideoWindow *s_instance;
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() );
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";
m_stream = xine_stream_new( m_xine, m_audioPort, m_videoPort );

@ -1,13 +1,14 @@
# SOME DESCRIPTIVE TITLE.
# This file is put in the public domain.
# Eduardo Herrera <edhu21@gmail.com>, 2023.
# Juan M Ayala <linux.zero@yahoo.com>, 2025.
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: 2023-03-21 23:14+0000\n"
"Last-Translator: Eduardo Herrera <edhu21@gmail.com>\n"
"PO-Revision-Date: 2025-01-20 18:16+0000\n"
"Last-Translator: Juan M Ayala <linux.zero@yahoo.com>\n"
"Language-Team: Spanish <https://mirror.git.trinitydesktop.org/weblate/"
"projects/applications/codeine-desktop-files/es/>\n"
"Language: es\n"
@ -15,12 +16,12 @@ msgstr ""
"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.16.1\n"
"X-Generator: Weblate 4.17\n"
#. Name
#: codeine.desktop:3 codeine_part.desktop:3
msgid "Codeine"
msgstr ""
msgstr "Codeine"
#. GenericName
#: codeine.desktop:5
@ -30,12 +31,13 @@ msgstr "Reproductor multimedia"
#. Comment
#: codeine.desktop:7
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
#: codeine_part.desktop:5
msgid "Embeddable Video Player"
msgstr ""
msgstr "Reproductor de Vídeo Integrable"
#. Name
#: 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.
# This file is put in the public domain.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
# Toad114514 <xiaolan2332021@163.com>, 2025.
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: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"PO-Revision-Date: 2025-01-28 07:12+0000\n"
"Last-Translator: Toad114514 <xiaolan2332021@163.com>\n"
"Language-Team: Chinese (Simplified) <https://mirror.git.trinitydesktop.org/"
"weblate/projects/applications/codeine-desktop-files/zh_Hans/>\n"
"Language: zh_CN\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"
#. Name
#: codeine.desktop:3 codeine_part.desktop:3
msgid "Codeine"
msgstr ""
msgstr "Codeine"
#. GenericName
#: codeine.desktop:5
@ -29,12 +30,12 @@ msgstr "媒体播放器"
#. Comment
#: codeine.desktop:7
msgid "Video player for TDE designed to be as simple as possible"
msgstr ""
msgstr "尽可能设计得简单的 TDE 视频播放器"
#. Comment
#: codeine_part.desktop:5
msgid "Embeddable Video Player"
msgstr ""
msgstr "内嵌视频播放器"
#. Name
#: codeine_play_dvd.desktop:8

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,26 +44,30 @@ msgstr ""
msgid "<b>Adjust video scale?"
msgstr ""
#: app/captureFrame.cpp:82
#: app/audioView.cpp:48 app/mainWindow.cpp:332
msgid "Show Analyzer"
msgstr ""
#: app/captureFrame.cpp:92
#, c-format
msgid "Capture - %1"
msgstr ""
#: app/captureFrame.cpp:98
#: app/captureFrame.cpp:108
msgid ""
"*.png|PNG Format\n"
"*.jpeg|JPEG Format"
msgstr ""
#: app/captureFrame.cpp:100
#: app/captureFrame.cpp:110
msgid "Save Frame"
msgstr ""
#: app/captureFrame.cpp:111
#: app/captureFrame.cpp:121
msgid "%1 saved successfully"
msgstr ""
#: app/captureFrame.cpp:113
#: app/captureFrame.cpp:123
#, c-format
msgid "Sorry, could not save %1"
msgstr ""
@ -80,19 +84,19 @@ msgstr ""
msgid "Determine &Automatically"
msgstr ""
#: app/insertAspectRatioMenuItems.cpp:18
#: app/insertAspectRatioMenuItems.cpp:17
msgid "&Square (1:1)"
msgstr ""
#: app/insertAspectRatioMenuItems.cpp:19
#: app/insertAspectRatioMenuItems.cpp:18
msgid "&4:3"
msgstr ""
#: app/insertAspectRatioMenuItems.cpp:20
#: app/insertAspectRatioMenuItems.cpp:19
msgid "Ana&morphic (16:9)"
msgstr ""
#: app/insertAspectRatioMenuItems.cpp:21
#: app/insertAspectRatioMenuItems.cpp:20
msgid "&DVB (2.11:1)"
msgstr ""
@ -132,79 +136,83 @@ msgstr ""
msgid "Patches, advice and moral support"
msgstr ""
#: app/mainWindow.cpp:131
msgid "&Subtitles"
#: app/mainWindow.cpp:143
msgid "Aspect Ratio"
msgstr ""
#: app/mainWindow.cpp:132
msgid "A&udio Channels"
#: app/mainWindow.cpp:149
msgid "Audio Channels"
msgstr ""
#: app/mainWindow.cpp:133
msgid "Aspect &Ratio"
#: app/mainWindow.cpp:155
msgid "Subtitles"
msgstr ""
#: app/mainWindow.cpp:250
#: app/mainWindow.cpp:277
msgid "Play &Media..."
msgstr ""
#: app/mainWindow.cpp:256
#: app/mainWindow.cpp:283
msgid "Record"
msgstr ""
#: app/mainWindow.cpp:258
#: app/mainWindow.cpp:285
msgid "Reset Video Scale"
msgstr ""
#: app/mainWindow.cpp:259 app/mainWindow.cpp:592
#: app/mainWindow.cpp:286 app/mainWindow.cpp:650
msgid "Media Information"
msgstr ""
#: app/mainWindow.cpp:260
#: app/mainWindow.cpp:287
msgid "Menu Toggle"
msgstr ""
#: app/mainWindow.cpp:261
#: app/mainWindow.cpp:288
msgid "&Capture Frame"
msgstr ""
#: app/mainWindow.cpp:263
#: app/mainWindow.cpp:290
msgid "Video Settings..."
msgstr ""
#: app/mainWindow.cpp:264
#: app/mainWindow.cpp:291
msgid "Configure xine..."
msgstr ""
#: app/mainWindow.cpp:266
#: app/mainWindow.cpp:293
msgid "Position Slider"
msgstr ""
#: app/mainWindow.cpp:364
msgid "Codeine was asked to open an empty URL; it cannot."
#: app/mainWindow.cpp:295
msgid "A&udio Channels"
msgstr ""
#: app/mainWindow.cpp:426
msgid "Supported Media Formats"
#: app/mainWindow.cpp:298
msgid "&Subtitles"
msgstr ""
#: app/mainWindow.cpp:426
msgid "All Files"
#: app/mainWindow.cpp:301
msgid "Aspect &Ratio"
msgstr ""
#: app/mainWindow.cpp:427
msgid "Select A File To Play"
#: app/mainWindow.cpp:425
msgid "Codeine was asked to open an empty URL; it cannot."
msgstr ""
#: app/mainWindow.cpp:607
msgid "&Determine Automatically"
#: app/mainWindow.cpp:487
msgid "Supported Media Formats"
msgstr ""
#: app/mainWindow.cpp:619
msgid "&Off"
#: app/mainWindow.cpp:487
msgid "All Files"
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"
msgstr ""
@ -251,19 +259,19 @@ msgstr ""
msgid "Codeine could not open the file: %1"
msgstr ""
#: app/stateChange.cpp:90
#: app/stateChange.cpp:92
msgid "&Pause"
msgstr ""
#: app/stateChange.cpp:90
#: app/stateChange.cpp:92
msgid "&Play"
msgstr ""
#: app/stateChange.cpp:154
#: app/stateChange.cpp:171
msgid "No media loaded"
msgstr ""
#: app/stateChange.cpp:157
#: app/stateChange.cpp:174
msgid "Paused"
msgstr ""
@ -347,128 +355,128 @@ msgstr ""
msgid "Pause"
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"
msgstr ""
#: app/volumeAction.cpp:85
#: app/volumeAction.cpp:127
#, c-format
msgid "Volume: %1"
msgid "Volume %1"
msgstr ""
#: app/xineConfig.cpp:62
#: app/xineConfig.cpp:46
msgid "Configure xine"
msgstr ""
#: app/xineConfig.cpp:87
#: app/xineConfig.cpp:68
msgid ""
"xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)."
"Xine's defaults are usually sensible and should not require modification. "
"However, full configurability is provided for your pleasure ;-)"
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."
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."
msgstr ""
#: app/xineEngine.cpp:244
#: app/xineEngine.cpp:254
#, c-format
msgid "Loading media: %1"
msgstr ""
#: app/xineEngine.cpp:349
#: app/xineEngine.cpp:360
#, c-format
msgid "Recording to: %1"
msgstr ""
#: app/xineEngine.cpp:380
#: app/xineEngine.cpp:393
msgid "Playback paused"
msgstr ""
#: app/xineEngine.cpp:385
#: app/xineEngine.cpp:398
msgid "Playback resumed"
msgstr ""
#: app/xineEngine.cpp:398
#: app/xineEngine.cpp:411
#, c-format
msgid "There is no input plugin that can read: %1."
msgstr ""
#: app/xineEngine.cpp:401
#: app/xineEngine.cpp:414
#, c-format
msgid "There is no demux plugin available for %1."
msgstr ""
#: app/xineEngine.cpp:404
#: app/xineEngine.cpp:417
#, c-format
msgid "Demuxing failed for %1."
msgstr ""
#: app/xineEngine.cpp:409
#: app/xineEngine.cpp:422
#, c-format
msgid "Internal error while attempting to play %1."
msgstr ""
#: app/xineEngine.cpp:497
msgid "xine cannot currently seek in flac media"
msgstr ""
#: app/xineEngine.cpp:675 app/xineEngine.cpp:683
#: app/xineEngine.cpp:748 app/xineEngine.cpp:756
#, c-format
msgid "Channel %1"
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."
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>"
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."
msgstr ""
#: app/xineEngine.cpp:788 part/xineEngine.cpp:295
#: app/xineEngine.cpp:861 part/xineEngine.cpp:295
msgid "The network appears unreachable."
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."
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>"
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>"
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>"
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>"
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."
msgstr ""
#: app/xineEngine.cpp:827 part/xineEngine.cpp:334
#: app/xineEngine.cpp:900 part/xineEngine.cpp:334
msgid "Sorry, no additional information is available."
msgstr ""
#: part/part.cpp:39
msgid "Mute"
msgstr ""
#: part/xineEngine.cpp:166
msgid "The Codeine video player could not find an input plugin for '%1'."
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