1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-05-01 22:00:04 +02:00
tomahawk/src/tomahawk/TomahawkWindow.cpp
2014-10-14 06:56:08 +02:00

1526 lines
46 KiB
C++

/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TomahawkWindow.h"
#include "ui_TomahawkWindow.h"
#include <QAction>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QShowEvent>
#include <QHideEvent>
#include <QInputDialog>
#include <QPixmap>
#include <QPropertyAnimation>
#include <QLineEdit>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QShortcut>
#include <QTimer>
#include <QToolBar>
#include <QToolButton>
#include "accounts/AccountManager.h"
#include "sourcetree/SourceTreeView.h"
#include "network/Servent.h"
#include "utils/TomahawkStyle.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/ProxyStyle.h"
#include "utils/WidgetDragFilter.h"
#include "utils/NetworkAccessManager.h"
#include "widgets/AccountsToolButton.h"
#include "widgets/AnimatedSplitter.h"
#include "widgets/ContainedMenuButton.h"
#include "thirdparty/Qocoa/qsearchfield.h"
#include "playlist/dynamic/GeneratorInterface.h"
#include "playlist/PlaylistModel.h"
#include "playlist/PlayableProxyModel.h"
#include "playlist/ContextView.h"
#include "playlist/TrackView.h"
#include "playlist/QueueView.h"
#include "jobview/JobStatusView.h"
#include "jobview/JobStatusModel.h"
#include "jobview/ErrorStatusMessage.h"
#include "jobview/JobStatusModel.h"
#include "sip/SipPlugin.h"
#include "filemetadata/ScanManager.h"
#include "viewpages/SearchViewPage.h"
#include "viewpages/whatsnew_0_8/WhatsNew_0_8.h"
#include "Playlist.h"
#include "Query.h"
#include "Artist.h"
#include "ViewManager.h"
#include "ActionCollection.h"
#include "AudioControls.h"
#include "dialogs/SettingsDialog.h"
#include "dialogs/DiagnosticsDialog.h"
#include "TomahawkSettings.h"
#include "SourceList.h"
#include "TomahawkTrayIcon.h"
#include "TomahawkApp.h"
#include "dialogs/LoadXSPFDialog.h"
#include "utils/ImageRegistry.h"
#include "utils/Logger.h"
#include "config.h"
#if defined( Q_OS_WIN )
#if defined ( WITH_QTSPARKLE )
#include <qtsparkle/Updater>
#endif
#include <shellapi.h>
#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
#include <windows.h>
#ifndef THBN_CLICKED
#define THBN_CLICKED 0x1800
#endif
#endif
#endif
using namespace Tomahawk;
using namespace Accounts;
TomahawkWindow::TomahawkWindow( QWidget* parent )
: QMainWindow( parent )
, TomahawkUtils::DpiScaler( this )
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
, m_buttonCreatedID( RegisterWindowMessage( L"TaskbarButtonCreated" ) )
, m_taskbarList( 0 )
#endif
, ui( new Ui::TomahawkWindow )
, m_searchWidget( 0 )
, m_trayIcon( 0 )
, m_audioRetryCounter( 0 )
{
setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) );
new ViewManager( this );
QueueView* queueView = new QueueView();
ViewManager::instance()->setQueue( queueView );
AudioEngine::instance()->setQueue( queueView->view()->trackView()->proxyModel()->playlistInterface() );
m_audioControls = new AudioControls( this );
ui->setupUi( this );
applyPlatformTweaks();
ui->centralWidget->setContentsMargins( 0, 0, 0, 0 );
TomahawkUtils::unmarginLayout( ui->centralWidget->layout() );
if ( QSystemTrayIcon::isSystemTrayAvailable() )
{
m_trayIcon = new TomahawkTrayIcon( this );
}
setupMenuBar();
setupToolBar();
setupSideBar();
setupStatusBar();
setupUpdateCheck();
loadSettings();
setupSignals();
setupShortcuts();
#ifdef Q_OS_WIN
connect( AudioEngine::instance(), SIGNAL( stateChanged( AudioState, AudioState ) ), SLOT( audioStateChanged( AudioState, AudioState ) ) );
#if QT_VERSION >= QT_VERSION_CHECK( 5, 2, 0 )
setupWindowsButtons();
#endif
#endif
if ( qApp->arguments().contains( "--debug" ) )
{
connect( ActionCollection::instance()->getAction( "crashNow" ), SIGNAL( triggered() ), SLOT( crashNow() ) );
}
// set initial state
audioStopped();
if ( TomahawkSettings::instance()->fullscreenEnabled() )
{
// Window must be fully constructed to toggle fullscreen mode. Queue it up.
QTimer::singleShot( 0, this, SLOT( toggleFullscreen() ) );
}
}
TomahawkWindow::~TomahawkWindow()
{
saveSettings();
delete ui;
}
void
TomahawkWindow::loadSettings()
{
TomahawkSettings* s = TomahawkSettings::instance();
// Workaround for broken window geometry restoring on Qt Cocoa when setUnifiedTitleAndToolBarOnMac is true.
// See http://bugreports.qt.nokia.com/browse/QTBUG-3116 and
// http://lists.qt.nokia.com/pipermail/qt-interest/2009-August/011491.html
// for the 'fix'
#ifdef QT_MAC_USE_COCOA
bool workaround = isVisible();
if ( workaround )
{
// make "invisible"
setWindowOpacity( 0 );
// let Qt update its frameStruts
show();
}
#endif
if ( !s->mainWindowGeometry().isEmpty() )
restoreGeometry( s->mainWindowGeometry() );
if ( !s->mainWindowState().isEmpty() )
restoreState( s->mainWindowState() );
if ( !s->mainWindowSplitterState().isEmpty() )
ui->splitter->restoreState( s->mainWindowSplitterState() );
// Always set stretch factor. If user hasn't manually set splitter sizes,
// this will ensure a sane default on all startups. If the user has, the manual
// size will override the default stretching
ui->splitter->setHandleWidth( 3 );
ui->splitter->setStretchFactor( 0, 0 );
ui->splitter->setStretchFactor( 1, 1 );
#ifdef QT_MAC_USE_COCOA
if ( workaround )
{
// Make it visible again
setWindowOpacity( 1 );
}
#endif
#ifndef Q_OS_MAC
bool mbVisible = s->menuBarVisible();
menuBar()->setVisible( mbVisible );
m_compactMenuAction->setVisible( !mbVisible );
ActionCollection::instance()->getAction( "toggleMenuBar" )->setText( mbVisible ? tr( "Hide Menu Bar" ) : tr( "Show Menu Bar" ) );
#endif
ActionCollection::instance()->getAction( "showOfflineSources" )->setChecked( TomahawkSettings::instance()->showOfflineSources() );
}
void
TomahawkWindow::saveSettings()
{
TomahawkSettings* s = TomahawkSettings::instance();
s->setMainWindowGeometry( saveGeometry() );
s->setMainWindowState( saveState() );
s->setMainWindowSplitterState( ui->splitter->saveState() );
s->setMenuBarVisible( menuBar()->isVisible() );
}
void
TomahawkWindow::applyPlatformTweaks()
{
// HACK: QtCurve causes an infinite loop on startup. This is because
// setStyle calls setPalette, which calls ensureBaseStyle, which loads
// QtCurve. QtCurve calls setPalette, which creates an infinite loop.
// We could simply not use ProxyStyle under QtCurve, but that would
// make the whole UI look like crap.
// Instead, we tell ProxyStyle that it's running under QtCurve, so it
// can intercept QStyle::polish (which in the base implementation does
// nothing and in QtCurve does evil things), and avoid forwarding it
// to QtCurve.
bool isQtCurve = false;
if ( QString( qApp->style()->metaObject()->className() ).toLower().contains( "qtcurve" ) )
isQtCurve = true;
qApp->setStyle( new ProxyStyle( isQtCurve ) );
#ifdef Q_OS_MAC
setUnifiedTitleAndToolBarOnMac( true );
delete ui->hline1;
delete ui->hline2;
#else
ui->hline1->setStyleSheet( "border: 1px solid gray;" );
ui->hline2->setStyleSheet( "border: 1px solid gray;" );
#endif
}
void
TomahawkWindow::setupToolBar()
{
m_toolbar = addToolBar( "TomahawkToolbar" );
m_toolbar->setObjectName( "TomahawkToolbar" );
m_toolbar->setMovable( false );
m_toolbar->setFloatable( false );
#ifdef Q_OS_MAC
m_toolbar->setIconSize( QSize( 22, 22 ) );
#else
m_toolbar->setIconSize( scaled( 22, 22 ) );
#endif
m_toolbar->setToolButtonStyle( Qt::ToolButtonIconOnly );
m_toolbar->setStyleSheet( "border-bottom: 0px" );
// If the toolbar is hidden accidentally it causes trouble on Unity because the user can't
// easily bring it back (TWK-1046). So we just prevent the user from hiding the toolbar.
// This should not affect Mac users.
m_toolbar->setContextMenuPolicy( Qt::PreventContextMenu );
#ifdef Q_OS_MAC
m_toolbar->installEventFilter( new WidgetDragFilter( m_toolbar ) );
#endif
m_backAction = m_toolbar->addAction( ImageRegistry::instance()->pixmap( RESPATH "images/back.svg", m_toolbar->iconSize() ),
tr( "Back" ),
ViewManager::instance(),
SLOT( historyBack() ) );
m_backAction->setToolTip( tr( "Go back one page" ) );
#ifdef Q_OS_MAC
m_backAction->setShortcut( QKeySequence( "Ctrl+Left" ) );
#else
m_backAction->setShortcut( QKeySequence( "Alt+Left" ) );
#endif
m_forwardAction = m_toolbar->addAction( ImageRegistry::instance()->pixmap( RESPATH "images/forward.svg", m_toolbar->iconSize() ),
tr( "Forward" ),
ViewManager::instance(),
SLOT( historyForward() ) );
m_forwardAction->setToolTip( tr( "Go forward one page" ) );
#ifdef Q_OS_MAC
m_forwardAction->setShortcut( QKeySequence( "Ctrl+Right" ) );
#else
m_forwardAction->setShortcut( QKeySequence( "Alt+Right" ) );
#endif
m_toolbarLeftBalancer = new QWidget( this );
m_toolbarLeftBalancer->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
m_toolbarLeftBalancer->setFixedWidth( 0 );
m_toolbar->addWidget( m_toolbarLeftBalancer )->setProperty( "kind", QString( "spacer" ) );
QWidget* toolbarLeftSpacer = new QWidget( this );
toolbarLeftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
m_toolbar->addWidget( toolbarLeftSpacer )->setProperty( "kind", QString( "spacer" ) );
m_searchWidget = new QSearchField( this );
m_searchWidget->setPlaceholderText( tr( "Search" ) );
m_searchWidget->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
m_searchWidget->setFixedWidth( scaledX( 340 ) );
connect( m_searchWidget, SIGNAL( returnPressed() ), SLOT( onFilterEdited() ) );
m_toolbar->addWidget( m_searchWidget )->setProperty( "kind", QString( "search" ) );
QWidget* rightSpacer = new QWidget( this );
rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
m_toolbar->addWidget( rightSpacer )->setProperty( "kind", QString( "spacer" ) );
m_toolbarRightBalancer = new QWidget( this );
m_toolbarRightBalancer->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred );
m_toolbarRightBalancer->setFixedWidth( 0 );
m_toolbar->addWidget( m_toolbarRightBalancer )->setProperty( "kind", QString( "spacer" ) );
m_accountsButton = new AccountsToolButton( m_toolbar );
m_toolbar->addWidget( m_accountsButton );
connect( m_accountsButton, SIGNAL( widthChanged() ), SLOT( balanceToolbar() ) );
#ifndef Q_OS_MAC
ContainedMenuButton* compactMenuButton = new ContainedMenuButton( m_toolbar );
compactMenuButton->setIcon( ImageRegistry::instance()->pixmap( RESPATH "images/configure.svg", m_toolbar->iconSize() ) );
compactMenuButton->setText( tr( "&Main Menu" ) );
compactMenuButton->setMenu( m_compactMainMenu );
compactMenuButton->setToolButtonStyle( Qt::ToolButtonIconOnly );
m_compactMenuAction = m_toolbar->addWidget( compactMenuButton );
//HACK: adding the toggle action to the window, otherwise the shortcut keys
// won't be picked up when the menu is hidden.
// This must be done for all menu bar actions that have shortcut keys :(
// Does not apply to Mac which always shows the menu bar.
addAction( ActionCollection::instance()->getAction( "playPause" ) );
addAction( ActionCollection::instance()->getAction( "toggleMenuBar" ) );
addAction( ActionCollection::instance()->getAction( "quit" ) );
#endif
onHistoryBackAvailable( false );
onHistoryForwardAvailable( false );
balanceToolbar();
}
void
TomahawkWindow::balanceToolbar()
{
int leftActionsWidth = 0;
int rightActionsWidth = 0;
bool flip = false;
foreach ( QAction* action, m_toolbar->actions() )
{
if ( action->property( "kind" ) == QString( "spacer" ) || !action->isVisible() )
{
continue;
}
else if ( action->property( "kind" ) == QString( "search" ) )
{
flip = true;
continue;
}
QWidget* widget = m_toolbar->widgetForAction( action );
if ( !flip ) //we accumulate on the left
{
leftActionsWidth += widget->sizeHint().width()
+ m_toolbar->layout()->spacing();
}
else //then, on the right
{
rightActionsWidth += widget->sizeHint().width()
+ m_toolbar->layout()->spacing();
}
}
if ( leftActionsWidth > rightActionsWidth )
{
m_toolbarLeftBalancer->setFixedWidth( 0 );
m_toolbarRightBalancer->setFixedWidth( leftActionsWidth - rightActionsWidth );
}
else
{
m_toolbarLeftBalancer->setFixedWidth( rightActionsWidth - leftActionsWidth );
m_toolbarRightBalancer->setFixedWidth( 0 );
}
}
void
TomahawkWindow::toggleLoved()
{
if ( !AudioEngine::instance()->currentTrack().isNull() )
{
AudioEngine::instance()->currentTrack()->track()->setLoved( !AudioEngine::instance()->currentTrack()->track()->loved() );
#ifdef Q_OS_WIN
updateWindowsLoveButton();
#endif
}
}
void
TomahawkWindow::setupSideBar()
{
// Delete fake designer widgets
delete ui->sidebarWidget;
delete ui->playlistWidget;
QWidget* sidebarWidget = new QWidget();
sidebarWidget->setLayout( new QVBoxLayout() );
m_sidebar = new AnimatedSplitter();
m_sidebar->setOrientation( Qt::Vertical );
m_sidebar->setChildrenCollapsible( false );
m_sourcetree = new SourceTreeView( this );
JobStatusView* jobsView = new JobStatusView( m_sidebar );
JobStatusModel* sourceModel = new JobStatusModel( jobsView );
m_jobsModel = new JobStatusSortModel( jobsView );
m_jobsModel->setJobModel( sourceModel );
jobsView->setModel( m_jobsModel );
m_sidebar->addWidget( m_sourcetree );
m_sidebar->addWidget( jobsView );
// m_sidebar->setGreedyWidget( 1 );
m_sidebar->hide( 1, false );
m_sidebar->hide( 2, false );
sidebarWidget->layout()->addWidget( m_sidebar );
sidebarWidget->setContentsMargins( 0, 0, 0, 0 );
sidebarWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
sidebarWidget->layout()->setMargin( 0 );
#ifndef Q_OS_MAC
sidebarWidget->layout()->setSpacing( 0 );
#endif
ui->splitter->addWidget( sidebarWidget );
ui->splitter->addWidget( ViewManager::instance()->widget() );
ui->splitter->setCollapsible( 0, false );
ui->splitter->setCollapsible( 1, false );
}
void
TomahawkWindow::setupStatusBar()
{
statusBar()->hide();
setStatusBar( 0 );
ui->centralWidget->layout()->addWidget( m_audioControls );
}
void
TomahawkWindow::setupShortcuts()
{
{
// Use Ctrl+F to focus the searchWidget
QShortcut* shortcut = new QShortcut( QKeySequence( QKeySequence::Find ), this );
QObject::connect( shortcut, SIGNAL( activated() ), m_searchWidget, SLOT( setFocus() ) );
}
{
// Use Ctrl+W to close current page
QShortcut* shortcut = new QShortcut( QKeySequence( QKeySequence::Close ), this );
QObject::connect( shortcut, SIGNAL( activated() ), ViewManager::instance(), SLOT( destroyCurrentPage() ) );
}
{
// Ctrl Up for raising the volume
QShortcut* shortcut = new QShortcut( QKeySequence( QKeySequence( "Ctrl+Up" ) ), this );
QObject::connect( shortcut, SIGNAL( activated() ), AudioEngine::instance(), SLOT( raiseVolume() ) );
}
{
// Ctrl Down for lowering the volume
QShortcut* shortcut = new QShortcut( QKeySequence( QKeySequence( "Ctrl+Down" ) ), this );
QObject::connect( shortcut, SIGNAL( activated() ), AudioEngine::instance(), SLOT( lowerVolume() ) );
}
}
void
TomahawkWindow::setupUpdateCheck()
{
#if defined( Q_OS_MAC ) && defined( HAVE_SPARKLE )
connect( ActionCollection::instance()->getAction( "checkForUpdates" ), SIGNAL( triggered( bool ) ),
SLOT( checkForUpdates() ) );
#elif defined( Q_OS_WIN ) && defined( WITH_QTSPARKLE )
QUrl updaterUrl;
if ( qApp->arguments().contains( "--debug" ) )
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin-debug" );
else
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin" );
qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this );
Q_ASSERT( Tomahawk::Utils::nam() != 0 );
updater->SetNetworkAccessManager( Tomahawk::Utils::nam() );
updater->SetVersion( TomahawkUtils::appFriendlyVersion() );
connect( ActionCollection::instance()->getAction( "checkForUpdates" ), SIGNAL( triggered() ),
updater, SLOT( CheckNow() ) );
#endif
}
#ifdef Q_OS_WIN
bool
TomahawkWindow::setupWindowsButtons()
{
#if QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
const GUID IID_ITaskbarList3 = { 0xea1afb91,0x9e28,0x4b86, { 0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf } };
HRESULT hr = S_OK;
THUMBBUTTONMASK dwMask = THUMBBUTTONMASK( THB_ICON | THB_TOOLTIP | THB_FLAGS );
m_thumbButtons[TP_PREVIOUS].dwMask = dwMask;
m_thumbButtons[TP_PREVIOUS].iId = TP_PREVIOUS;
m_thumbButtons[TP_PREVIOUS].hIcon = thumbIcon(TomahawkUtils::PrevButton);
m_thumbButtons[TP_PREVIOUS].dwFlags = THBF_ENABLED;
m_thumbButtons[TP_PREVIOUS].szTip[ tr( "Back" ).toWCharArray( m_thumbButtons[TP_PREVIOUS].szTip ) ] = 0;
m_thumbButtons[TP_PLAY_PAUSE].dwMask = dwMask;
m_thumbButtons[TP_PLAY_PAUSE].iId = TP_PLAY_PAUSE;
m_thumbButtons[TP_PLAY_PAUSE].hIcon = thumbIcon(TomahawkUtils::PlayButton);
m_thumbButtons[TP_PLAY_PAUSE].dwFlags = THBF_ENABLED;
m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0;
m_thumbButtons[TP_NEXT].dwMask = dwMask;
m_thumbButtons[TP_NEXT].iId = TP_NEXT;
m_thumbButtons[TP_NEXT].hIcon = thumbIcon(TomahawkUtils::NextButton);
m_thumbButtons[TP_NEXT].dwFlags = THBF_ENABLED;
m_thumbButtons[TP_NEXT].szTip[ tr( "Next" ).toWCharArray( m_thumbButtons[TP_NEXT].szTip ) ] = 0;
m_thumbButtons[3].dwMask = dwMask;
m_thumbButtons[3].iId = -1;
m_thumbButtons[3].hIcon = 0;
m_thumbButtons[3].dwFlags = THBF_NOBACKGROUND | THBF_DISABLED;
m_thumbButtons[3].szTip[0] = 0;
m_thumbButtons[TP_LOVE].dwMask = dwMask;
m_thumbButtons[TP_LOVE].iId = TP_LOVE;
m_thumbButtons[TP_LOVE].hIcon = thumbIcon(TomahawkUtils::NotLoved);
m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED;
m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0;
if ( S_OK == CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_taskbarList ) )
{
hr = m_taskbarList->HrInit();
if ( SUCCEEDED( hr ) )
{
hr = m_taskbarList->ThumbBarAddButtons( (HWND)winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons );
}
else
{
m_taskbarList->Release();
m_taskbarList = 0;
}
}
return SUCCEEDED( hr );
#else
m_taskbarList = new QWinThumbnailToolBar( this );
m_taskbarList->setWindow( this->windowHandle() );
QWinThumbnailToolButton *back = new QWinThumbnailToolButton( m_taskbarList );
back->setToolTip( tr( "Back" ) );
back->setIcon( thumbIcon( TomahawkUtils::PrevButton ) );
connect( back, SIGNAL( clicked() ) , AudioEngine::instance() , SLOT( previous() ) );
m_taskbarList->addButton(back);
QWinThumbnailToolButton *play = new QWinThumbnailToolButton( m_taskbarList );
play->setToolTip( tr( "Play" ) );
play->setIcon( thumbIcon( TomahawkUtils::PlayButton ) );
connect( play, SIGNAL( clicked() ) , AudioEngine::instance() , SLOT( playPause() ) );
m_taskbarList->addButton(play);
QWinThumbnailToolButton *next = new QWinThumbnailToolButton( m_taskbarList );
next->setToolTip( tr( "Next" ) );
next->setIcon( thumbIcon( TomahawkUtils::NextButton ) );
connect( next, SIGNAL( clicked() ) , AudioEngine::instance() , SLOT( next() ) );
m_taskbarList->addButton(next);
QWinThumbnailToolButton *space = new QWinThumbnailToolButton( m_taskbarList );
space->setVisible( true );
space->setFlat( true );
m_taskbarList->addButton(space);
QWinThumbnailToolButton *love = new QWinThumbnailToolButton( m_taskbarList );
love->setToolTip( tr( "Love" ) );
love->setIcon( thumbIcon( TomahawkUtils::NotLoved ) );
love->setInteractive( false );
connect( love , SIGNAL( clicked() ) , this , SLOT( toggleLoved() ) );
m_taskbarList->addButton(love);
return true;
#endif//QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
}
#if QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
HICON
TomahawkWindow::thumbIcon( TomahawkUtils::ImageType type )
{
static QMap<TomahawkUtils::ImageType,HICON> thumbIcons;
if ( !thumbIcons.contains( type ) )
{
QPixmap pix ( TomahawkUtils::defaultPixmap(type , TomahawkUtils::Original, QSize( 40, 40 ) ) );
thumbIcons[type] = pix.toWinHICON();
}
return thumbIcons[type];
}
#else
QIcon
TomahawkWindow::thumbIcon(TomahawkUtils::ImageType type)
{
return TomahawkUtils::defaultPixmap( type , TomahawkUtils::Original, QSize( 40, 40 ) );
}
#endif//QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
#endif
void
TomahawkWindow::setupSignals()
{
// <From AudioEngine>
connect( AudioEngine::instance(), SIGNAL( error( AudioEngine::AudioErrorCode ) ), SLOT( onAudioEngineError( AudioEngine::AudioErrorCode ) ) );
connect( AudioEngine::instance(), SIGNAL( loading( const Tomahawk::result_ptr& ) ), SLOT( onPlaybackLoading( const Tomahawk::result_ptr& ) ) );
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( audioStarted() ) );
connect( AudioEngine::instance(), SIGNAL( finished( Tomahawk::result_ptr ) ), SLOT( audioFinished() ) );
connect( AudioEngine::instance(), SIGNAL( resumed() ), SLOT( audioStarted() ) );
connect( AudioEngine::instance(), SIGNAL( paused() ), SLOT( audioPaused() ) );
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( audioStopped() ) );
// <Menu Items>
ActionCollection *ac = ActionCollection::instance();
connect( ac->getAction( "preferences" ), SIGNAL( triggered() ), SLOT( showSettingsDialog() ) );
connect( ac->getAction( "diagnostics" ), SIGNAL( triggered() ), SLOT( showDiagnosticsDialog() ) );
connect( ac->getAction( "legalInfo" ), SIGNAL( triggered() ), SLOT( legalInfo() ) );
connect( ac->getAction( "reportBug" ), SIGNAL( triggered() ), SLOT( reportBug() ) );
connect( ac->getAction( "getSupport" ), SIGNAL( triggered() ), SLOT( getSupport() ) );
connect( ac->getAction( "helpTranslate" ), SIGNAL( triggered() ), SLOT( helpTranslate() ) );
connect( ac->getAction( "openLogfile" ), SIGNAL( triggered() ), SLOT( openLogfile() ) );
connect( ac->getAction( "updateCollection" ), SIGNAL( triggered() ), SLOT( updateCollectionManually() ) );
connect( ac->getAction( "rescanCollection" ), SIGNAL( triggered() ), SLOT( rescanCollectionManually() ) );
connect( ac->getAction( "loadXSPF" ), SIGNAL( triggered() ), SLOT( loadSpiff() ) );
connect( ac->getAction( "whatsnew_0_8" ), SIGNAL( triggered() ), SLOT( showWhatsNew_0_8() ) );
connect( ac->getAction( "aboutTomahawk" ), SIGNAL( triggered() ), SLOT( showAboutTomahawk() ) );
connect( ac->getAction( "quit" ), SIGNAL( triggered() ), qApp, SLOT( quit() ) );
connect( ac->getAction( "showOfflineSources" ), SIGNAL( triggered() ), SLOT( showOfflineSources() ) );
#if defined( Q_OS_MAC )
connect( ac->getAction( "minimize" ), SIGNAL( triggered() ), SLOT( minimize() ) );
connect( ac->getAction( "zoom" ), SIGNAL( triggered() ), SLOT( maximize() ) );
connect( ac->getAction( "fullscreen" ), SIGNAL( triggered() ), SLOT( toggleFullscreen() ) );
#else
connect( ac->getAction( "toggleMenuBar" ), SIGNAL( triggered() ), SLOT( toggleMenuBar() ) );
#endif
connect( ViewManager::instance(), SIGNAL( historyBackAvailable( bool ) ), SLOT( onHistoryBackAvailable( bool ) ) );
connect( ViewManager::instance(), SIGNAL( historyForwardAvailable( bool ) ), SLOT( onHistoryForwardAvailable( bool ) ) );
}
void
TomahawkWindow::setupMenuBar()
{
// Always create a menubar, but only create a compactMenu on Windows and X11
m_menuBar = ActionCollection::instance()->createMenuBar( this );
m_menuBar->setFont( TomahawkUtils::systemFont() );
setMenuBar( m_menuBar );
#ifndef Q_OS_MAC
m_compactMainMenu = ActionCollection::instance()->createCompactMenu( this );
#endif
}
bool
TomahawkWindow::eventFilter( QObject* obj, QEvent* event )
{
if ( event->type() == QEvent::MouseButtonPress )
{
QMouseEvent* me = static_cast<QMouseEvent*>(event);
switch ( me->button() )
{
case Qt::XButton1:
m_backAction->trigger();
break;
case Qt::XButton2:
m_forwardAction->trigger();
break;
default:
break;
}
}
return QObject::eventFilter( obj, event );
}
void
TomahawkWindow::changeEvent( QEvent* e )
{
QMainWindow::changeEvent( e );
switch ( e->type() )
{
case QEvent::LanguageChange:
ui->retranslateUi( this );
break;
default:
break;
}
}
void
TomahawkWindow::closeEvent( QCloseEvent* e )
{
#ifndef Q_OS_MAC
if ( e->spontaneous() && QSystemTrayIcon::isSystemTrayAvailable() )
{
hide();
e->ignore();
return;
}
#endif
QMainWindow::closeEvent( e );
}
void
TomahawkWindow::showEvent( QShowEvent* e )
{
QMainWindow::showEvent( e );
#if defined( Q_OS_MAC )
ActionCollection::instance()->getAction( "minimize" )->setDisabled( false );
ActionCollection::instance()->getAction( "zoom" )->setDisabled( false );
#endif
}
void
TomahawkWindow::hideEvent( QHideEvent* e )
{
QMainWindow::hideEvent( e );
#if defined( Q_OS_MAC )
ActionCollection::instance()->getAction( "minimize" )->setDisabled( true );
ActionCollection::instance()->getAction( "zoom" )->setDisabled( true );
#endif
}
void
TomahawkWindow::keyPressEvent( QKeyEvent* e )
{
bool accept = true;
#if ! defined ( Q_OS_MAC )
#define KEY_PRESSED Q_FUNC_INFO << "Multimedia Key Pressed:"
switch ( e->key() )
{
case Qt::Key_MediaPlay:
tLog() << KEY_PRESSED << "Play";
AudioEngine::instance()->playPause();
break;
case Qt::Key_MediaStop:
tLog() << KEY_PRESSED << "Stop";
AudioEngine::instance()->stop();
break;
case Qt::Key_MediaPrevious:
tLog() << KEY_PRESSED << "Previous";
AudioEngine::instance()->previous();
break;
case Qt::Key_MediaNext:
tLog() << KEY_PRESSED << "Next";
AudioEngine::instance()->next();
break;
case Qt::Key_MediaPause:
tLog() << KEY_PRESSED << "Pause";
AudioEngine::instance()->pause();
break;
case Qt::Key_MediaTogglePlayPause:
tLog() << KEY_PRESSED << "PlayPause";
AudioEngine::instance()->playPause();
break;
case Qt::Key_MediaRecord:
default:
accept = false;
}
#else
accept = false;
#endif
if ( accept )
e->accept();
QMainWindow::keyPressEvent( e );
}
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
bool
TomahawkWindow::winEvent( MSG* msg, long* result )
{
Q_UNUSED(result);
#define TB_PRESSED Q_FUNC_INFO << "Taskbar Button Pressed:"
switch ( msg->message )
{
case WM_COMMAND:
if ( HIWORD( msg->wParam ) == THBN_CLICKED )
{
switch ( TB_STATES( LOWORD( msg->wParam ) ) )
{
case TP_PREVIOUS:
tLog() << TB_PRESSED << "Previous";
AudioEngine::instance()->previous();
break;
case TP_PLAY_PAUSE:
tLog() << TB_PRESSED << "Play/Pause";
AudioEngine::instance()->playPause();
break;
case TP_NEXT:
tLog() << TB_PRESSED << "Next";
AudioEngine::instance()->next();
break;
case TP_LOVE:
tLog() << TB_PRESSED << "Love";
toggleLoved();
break;
}
return true;
}
break;
}
if ( msg->message == m_buttonCreatedID )
return setupWindowsButtons();
return false;
}
#endif//defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
void
TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState )
{
Q_UNUSED(oldState);
#ifndef Q_OS_WIN
Q_UNUSED(newState);
#else
#if QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
if ( m_taskbarList == 0 )
return;
switch ( newState )
{
case AudioEngine::Playing:
{
m_thumbButtons[TP_PLAY_PAUSE].hIcon = thumbIcon(TomahawkUtils::PauseButton);
m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0;
updateWindowsLoveButton();
}
break;
case AudioEngine::Paused:
{
m_thumbButtons[TP_PLAY_PAUSE].hIcon = thumbIcon(TomahawkUtils::PlayButton);
m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0;
}
break;
case AudioEngine::Stopped:
{
if ( !AudioEngine::instance()->currentTrack().isNull() )
{
disconnect( AudioEngine::instance()->currentTrack()->track().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( updateWindowsLoveButton() ) );
}
m_thumbButtons[TP_PLAY_PAUSE].hIcon = thumbIcon(TomahawkUtils::PlayButton);
m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0;
m_thumbButtons[TP_LOVE].hIcon = thumbIcon(TomahawkUtils::NotLoved);
m_thumbButtons[TP_LOVE].dwFlags = THBF_DISABLED;
}
break;
default:
return;
}
m_taskbarList->ThumbBarUpdateButtons( (HWND)winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons );
#else
QWinThumbnailToolButton *play = m_taskbarList->buttons()[ TP_PLAY_PAUSE ];
switch ( newState )
{
case AudioEngine::Playing:
{
play->setIcon( thumbIcon(TomahawkUtils::PauseButton) );
play->setToolTip( tr( "Pause" ) );
updateWindowsLoveButton();
}
break;
case AudioEngine::Paused:
{
play->setIcon( thumbIcon(TomahawkUtils::PlayButton) );
play->setToolTip( tr( "Play" ) );
}
break;
case AudioEngine::Stopped:
{
if ( !AudioEngine::instance()->currentTrack().isNull() )
{
disconnect( AudioEngine::instance()->currentTrack()->track().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( updateWindowsLoveButton() ) );
}
play->setIcon( thumbIcon(TomahawkUtils::PlayButton) );
play->setToolTip( tr( "Play" ) );
QWinThumbnailToolButton *love = m_taskbarList->buttons()[ TP_LOVE ];
love->setIcon( thumbIcon(TomahawkUtils::NotLoved) );
love->setInteractive( false );
}
break;
default:
return;
}
#endif//QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
#endif//Q_OS_WIN
}
void
TomahawkWindow::updateWindowsLoveButton()
{
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
if ( m_taskbarList == 0 )
return;
if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->track()->loved() )
{
m_thumbButtons[TP_LOVE].hIcon = thumbIcon(TomahawkUtils::Loved);
m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0;
}
else
{
m_thumbButtons[TP_LOVE].hIcon = thumbIcon(TomahawkUtils::NotLoved);
m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0;
}
m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED;
m_taskbarList->ThumbBarUpdateButtons( (HWND)winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons );
#elif defined(Q_OS_WIN)
QWinThumbnailToolButton *love = m_taskbarList->buttons()[ TP_LOVE ];
if ( !AudioEngine::instance()->currentTrack().isNull() )
{
love->setInteractive(true);
if ( AudioEngine::instance()->currentTrack()->track()->loved() )
{
love->setIcon(thumbIcon(TomahawkUtils::Loved));
love->setToolTip( tr( "Unlove" ) );
}
else
{
love->setIcon( thumbIcon(TomahawkUtils::NotLoved) );
love->setToolTip( tr( "Love" ) );
}
}
else
{
love->setInteractive(false);
love->setIcon( thumbIcon(TomahawkUtils::NotLoved) );
love->setToolTip( tr( "Love" ) );
}
#endif//defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK( 5, 2, 0 )
}
void
TomahawkWindow::onHistoryBackAvailable( bool avail )
{
m_backAction->setEnabled( avail );
}
void
TomahawkWindow::onHistoryForwardAvailable( bool avail )
{
m_forwardAction->setEnabled( avail );
}
void
TomahawkWindow::showSettingsDialog()
{
if ( m_settingsDialog )
return;
m_settingsDialog = new SettingsDialog;
// This needs to be a QueuedConnection, so that deleteLater() actually works.
connect( m_settingsDialog.data(), SIGNAL( finished( bool ) ),
m_settingsDialog.data(), SLOT( deleteLater() ), Qt::QueuedConnection );
m_settingsDialog->show();
}
void
TomahawkWindow::showDiagnosticsDialog()
{
DiagnosticsDialog win;
win.exec();
}
void
TomahawkWindow::legalInfo()
{
QDesktopServices::openUrl( QUrl( "http://www.tomahawk-player.org/legal.html" ) );
}
void
TomahawkWindow::getSupport()
{
QDesktopServices::openUrl( QUrl( "https://tomahawk.uservoice.com" ) );
}
void
TomahawkWindow::reportBug()
{
QDesktopServices::openUrl( QUrl( "https://bugs.tomahawk-player.org" ) );
}
void
TomahawkWindow::helpTranslate()
{
QDesktopServices::openUrl( QUrl( "https://www.transifex.com/projects/p/tomahawk/" ) );
}
void
TomahawkWindow::openLogfile()
{
#ifdef WIN32
ShellExecuteW( 0, 0, (LPCWSTR)Logger::logFile().utf16(), 0, 0, SW_SHOWNORMAL );
#else
QDesktopServices::openUrl( QUrl::fromLocalFile( Logger::logFile() ) );
#endif
}
void
TomahawkWindow::updateCollectionManually()
{
if ( TomahawkSettings::instance()->hasScannerPaths() )
ScanManager::instance()->runNormalScan();
}
void
TomahawkWindow::rescanCollectionManually()
{
if ( TomahawkSettings::instance()->hasScannerPaths() )
ScanManager::instance()->runFullRescan();
}
void
TomahawkWindow::showOfflineSources()
{
m_sourcetree->showOfflineSources(
ActionCollection::instance()->getAction( "showOfflineSources" )->isChecked() );
TomahawkSettings::instance()->setShowOfflineSources(
ActionCollection::instance()->getAction( "showOfflineSources" )->isChecked() );
}
void
TomahawkWindow::fullScreenEntered()
{
TomahawkSettings::instance()->setFullscreenEnabled( true );
// statusBar()->setSizeGripEnabled( false );
// Since we just disabled the size-grip the entire statusbar will shift a bit to the right
// The volume bar would now have no margin to the right screen edge. Prevent that.
// QMargins margins = statusBar()->contentsMargins();
// margins.setRight( 24 );
// statusBar()->setContentsMargins( margins );
#if defined( Q_WS_MAC )
ActionCollection::instance()->getAction( "fullscreen" )->setText( tr( "Exit Full Screen" ) );
#endif
}
void
TomahawkWindow::fullScreenExited()
{
TomahawkSettings::instance()->setFullscreenEnabled( false );
// statusBar()->setSizeGripEnabled( true );
// Since we just enabled the size-grip the entire statusbar will shift a bit to the left
// The volume bar would now have too big a margin to the right screen edge. Prevent that.
// QMargins margins = statusBar()->contentsMargins();
// margins.setRight( 0 );
// statusBar()->setContentsMargins( margins );
#if defined( Q_WS_MAC )
ActionCollection::instance()->getAction( "fullscreen" )->setText( tr( "Enter Full Screen" ) );
#endif
}
void
TomahawkWindow::loadSpiff()
{
LoadXSPFDialog* diag = new LoadXSPFDialog( this, Qt::Sheet );
#ifdef Q_OS_MAC
connect( diag, SIGNAL( finished( int ) ), this, SLOT( loadXspfFinished( int ) ) );
diag->show();
#else
QPointer< LoadXSPFDialog > safe( diag );
int ret = diag->exec();
if ( !safe.isNull() && ret == QDialog::Accepted )
{
QUrl url = QUrl::fromUserInput( safe.data()->xspfUrl() );
bool autoUpdate = safe.data()->autoUpdate();
XSPFLoader* loader = new XSPFLoader( true, autoUpdate );
connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) );
connect( loader, SIGNAL( ok( Tomahawk::playlist_ptr ) ), SLOT( onXSPFOk( Tomahawk::playlist_ptr ) ) );
loader->load( url );
}
#endif
}
void
TomahawkWindow::loadXspfFinished( int ret )
{
LoadXSPFDialog* d = qobject_cast< LoadXSPFDialog* >( sender() );
Q_ASSERT( d );
if ( ret == QDialog::Accepted )
{
QUrl url = QUrl::fromUserInput( d->xspfUrl() );
bool autoUpdate = d->autoUpdate();
XSPFLoader* loader = new XSPFLoader( true, autoUpdate );
connect( loader, SIGNAL( error( XSPFLoader::XSPFErrorCode ) ), SLOT( onXSPFError( XSPFLoader::XSPFErrorCode ) ) );
connect( loader, SIGNAL( ok( Tomahawk::playlist_ptr ) ), SLOT( onXSPFOk( Tomahawk::playlist_ptr ) ) );
loader->load( url );
}
d->deleteLater();
}
void
TomahawkWindow::onXSPFOk( const Tomahawk::playlist_ptr& pl )
{
ViewManager::instance()->show( pl );
}
void
TomahawkWindow::onXSPFError( XSPFLoader::XSPFErrorCode error )
{
switch ( error )
{
case XSPFLoader::ParseError:
QMessageBox::critical( this, tr( "XSPF Error" ), tr( "This is not a valid XSPF playlist." ) );
break;
case XSPFLoader::InvalidTrackError:
QMessageBox::warning( this, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok );
break;
default:
//FIXME: This includes FetchError
break;
}
}
void
TomahawkWindow::onAudioEngineError( AudioEngine::AudioErrorCode /* error */ )
{
QString msg;
#ifdef Q_OS_LINUX
msg = tr( "Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed." );
#else
msg = tr( "Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped." );
#endif
tLog() << msg;
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( msg, 15 ) );
if ( m_audioRetryCounter < 3 )
AudioEngine::instance()->play();
m_audioRetryCounter++;
}
void
TomahawkWindow::createStation()
{
QString title = tr( "Station" );
bool ok;
QString playlistName = QInputDialog( this, Qt::Sheet ).getText( this, tr( "Create New Station" ), tr( "Name:" ), QLineEdit::Normal, title, &ok );
if ( !ok )
return;
if ( playlistName.isEmpty() || playlistName == title )
{
QList< dynplaylist_ptr > pls = SourceList::instance()->getLocal()->dbCollection()->stations();
QStringList titles;
foreach ( const playlist_ptr& pl, pls )
titles << pl->title();
playlistName = title;
int i = 2;
while ( titles.contains( playlistName ) )
{
playlistName = QString( "%1 (%2)" ).arg( title ).arg( i++ );
}
}
QString info = ""; // FIXME
QString creator = ""; // FIXME
dynplaylist_ptr playlist = DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), playlistName, info, creator, OnDemand, false );
playlist->setMode( OnDemand );
playlist->createNewRevision( uuid(), playlist->currentrevision(), playlist->type(), playlist->generator()->controls() );
ViewManager::instance()->show( playlist );
}
void
TomahawkWindow::createPlaylist()
{
QString title = tr( "Playlist" );
bool ok;
QString playlistName = QInputDialog( this, Qt::Sheet ).getText( this, tr( "Create New Playlist" ), tr( "Name:" ), QLineEdit::Normal, title, &ok );
if ( !ok )
return;
if ( playlistName.isEmpty() || playlistName == title )
{
QList< playlist_ptr > pls = SourceList::instance()->getLocal()->dbCollection()->playlists();
QStringList titles;
foreach ( const playlist_ptr& pl, pls )
titles << pl->title();
playlistName = title;
int i = 2;
while ( titles.contains( playlistName ) )
{
playlistName = QString( "%1 (%2)" ).arg( title ).arg( i++ );
}
}
QString info = ""; // FIXME?
QString creator = ""; // FIXME?
playlist_ptr playlist = Tomahawk::Playlist::create( SourceList::instance()->getLocal(), uuid(), playlistName, info, creator, false, QList< query_ptr>() );
ViewManager::instance()->show( playlist );
}
void
TomahawkWindow::audioStarted()
{
m_audioRetryCounter = 0;
ActionCollection::instance()->getAction( "playPause" )->setIcon( ImageRegistry::instance()->icon( RESPATH "images/pause.svg" ) );
ActionCollection::instance()->getAction( "playPause" )->setText( tr( "Pause" ) );
ActionCollection::instance()->getAction( "stop" )->setEnabled( true );
#ifdef Q_OS_WIN
connect( AudioEngine::instance()->currentTrack()->track().data(), SIGNAL( socialActionsLoaded() ), SLOT( updateWindowsLoveButton() ) );
#endif
}
void
TomahawkWindow::audioFinished()
{
#ifdef Q_OS_WIN
disconnect( AudioEngine::instance()->currentTrack()->track().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( updateWindowsLoveButton() ) );
#endif
}
void
TomahawkWindow::audioPaused()
{
ActionCollection::instance()->getAction( "playPause" )->setIcon( ImageRegistry::instance()->icon( RESPATH "images/play.svg" ) );
ActionCollection::instance()->getAction( "playPause" )->setText( tr( "&Play" ) );
}
void
TomahawkWindow::audioStopped()
{
audioPaused();
ActionCollection::instance()->getAction( "stop" )->setEnabled( false );
m_currentTrack = result_ptr();
setWindowTitle( m_windowTitle );
}
void
TomahawkWindow::onPlaybackLoading( const Tomahawk::result_ptr result )
{
m_currentTrack = result;
setWindowTitle( m_windowTitle );
}
void
TomahawkWindow::setWindowTitle( const QString& title )
{
m_windowTitle = title;
if ( m_currentTrack.isNull() )
QMainWindow::setWindowTitle( title );
else
{
QString s = tr( "%1 by %2", "track, artist name" ).arg( m_currentTrack->track()->track(), m_currentTrack->track()->artist() );
QMainWindow::setWindowTitle( tr( "%1 - %2", "current track, some window title" ).arg( s, title ) );
}
}
void
TomahawkWindow::showAboutTomahawk()
{
QString head, desc;
#ifdef QT_DEBUG
head = tr( "<h2><b>Tomahawk %1<br/>(%2)</h2>" )
.arg( TomahawkUtils::appFriendlyVersion() )
.arg( qApp->applicationVersion() );
#else
head = tr( "<h2><b>Tomahawk %1</h2>" )
.arg( TomahawkUtils::appFriendlyVersion() );
#endif
const QString copyright( tr( "Copyright 2010 - 2014" ) );
const QString thanksto( tr( "Thanks to:" ) );
desc = QString( "%1<br/>Christian Muehlhaeuser &lt;muesli@tomahawk-player.org&gt;<br/><br/>"
"%2 Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Hugo Lindstr&ouml;m, Michael Zanetti, Teo Mrnjavac, Christopher Reichert, Uwe L. Korn, Patrick von Reth, Harald Sitter, Syd Lawrence, Jordi Verd&uacute; Orts" )
.arg( copyright )
.arg( thanksto );
QMessageBox::about( this, tr( "About Tomahawk" ), head + desc );
}
void
TomahawkWindow::showWhatsNew_0_8()
{
ViewManager::instance()->showDynamicPage( Tomahawk::Widgets::WHATSNEW_0_8_VIEWPAGE_NAME );
}
void
TomahawkWindow::checkForUpdates()
{
#ifdef Q_OS_MAC
Tomahawk::checkForUpdates();
#endif
}
void
TomahawkWindow::onSearch( const QString& search )
{
if ( !search.trimmed().isEmpty() )
{
if ( search.startsWith( "tomahawk:" ) )
{
APP->loadUrl( search );
}
else
{
ViewManager::instance()->show( new SearchWidget( search, this ) );
}
}
}
void
TomahawkWindow::onFilterEdited()
{
onSearch( m_searchWidget->text() );
m_searchWidget->clear();
}
void
TomahawkWindow::minimize()
{
if ( isMinimized() )
{
showNormal();
}
else
{
showMinimized();
}
}
void
TomahawkWindow::maximize()
{
if ( isMaximized() )
{
showNormal();
}
else
{
showMaximized();
}
}
void
TomahawkWindow::toggleFullscreen()
{
tDebug() << Q_FUNC_INFO;
#if defined( Q_WS_MAC )
Tomahawk::toggleFullscreen();
#endif
}
void
TomahawkWindow::crashNow()
{
TomahawkUtils::crash();
}
void
TomahawkWindow::toggleMenuBar() //SLOT
{
#ifndef Q_OS_MAC
if ( menuBar()->isVisible() )
{
menuBar()->setVisible( false );
ActionCollection::instance()->getAction( "toggleMenuBar" )->setText( tr( "Show Menu Bar" ) );
m_compactMenuAction->setVisible( true );
}
else
{
m_compactMenuAction->setVisible( false );
ActionCollection::instance()->getAction( "toggleMenuBar" )->setText( tr( "Hide Menu Bar" ) );
menuBar()->setVisible( true );
}
balanceToolbar();
saveSettings();
#endif
}
AudioControls*
TomahawkWindow::audioControls()
{
return m_audioControls;
}
SourceTreeView*
TomahawkWindow::sourceTreeView() const
{
return m_sourcetree;
}