diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 99f56e808..bfc906ae2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -83,7 +83,9 @@ ENDIF()
SET( tomahawkUI ${tomahawkUI}
TomahawkWindow.ui
DiagnosticsDialog.ui
- StackedSettingsDialog.ui
+ Settings_Accounts.ui
+ Settings_Advanced.ui
+ Settings_Collection.ui
ProxyDialog.ui
AudioControls.ui
diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp
index 06217c8aa..4aafe6386 100644
--- a/src/SettingsDialog.cpp
+++ b/src/SettingsDialog.cpp
@@ -53,75 +53,78 @@
#include "utils/Logger.h"
#include "accounts/AccountFactoryWrapper.h"
#include "accounts/spotify/SpotifyAccount.h"
+#include "thirdparty/Qocoa/qtoolbartabdialog.h"
#include "ui_ProxyDialog.h"
-#include "ui_StackedSettingsDialog.h"
+#include "ui_Settings_Accounts.h"
+#include "ui_Settings_Collection.h"
+#include "ui_Settings_Advanced.h"
using namespace Tomahawk;
using namespace Accounts;
-SettingsDialog::SettingsDialog( QWidget *parent )
- : QDialog( parent )
- , ui( new Ui_StackedSettingsDialog )
- , m_proxySettings( this )
+SettingsDialog::SettingsDialog(QObject *parent )
+ : QObject( parent )
+ , m_accountsWidgetUi( new Ui_Settings_Accounts )
+ , m_accountsWidget( new QWidget )
+ , m_collectionWidgetUi( new Ui_Settings_Collection )
+ , m_collectionWidget( new QWidget )
+ , m_advancedWidgetUi( new Ui_Settings_Advanced )
+ , m_advancedWidget( new QWidget )
+ , m_proxySettings( 0 )
, m_rejected( false )
, m_restartRequired( false )
, m_accountModel( 0 )
, m_sipSpinner( 0 )
{
- ui->setupUi( this );
+ m_accountsWidgetUi->setupUi( m_accountsWidget );
+ m_collectionWidgetUi->setupUi( m_collectionWidget );
+ m_advancedWidgetUi->setupUi( m_advancedWidget );
+
+ m_dialog = new QToolbarTabDialog;
+
TomahawkSettings* s = TomahawkSettings::instance();
- TomahawkUtils::unmarginLayout( layout() );
- TomahawkUtils::unmarginLayout( ui->horizontalLayout );
+// TomahawkUtils::unmarginLayout( layout() );
+// TomahawkUtils::unmarginLayout( ui->horizontalLayout );
-#ifdef Q_WS_X11
- ui->stackedWidget->setContentsMargins( 4, 4, 4, 4 );
-#else
- ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 );
-#endif
- ui->checkBoxReporter->setChecked( s->crashReporterEnabled() );
- ui->checkBoxHttp->setChecked( s->httpEnabled() );
-
- QFrame *sepLine = new QFrame( this );
- sepLine->setFrameShape( QFrame::HLine );
- sepLine->setFrameShadow( QFrame::Sunken );
- ui->horizontalLayout->insertWidget( 0, sepLine );
-
- m_toolBar = new QToolBar( tr( "Tomahawk Settings" ), this );
- ui->horizontalLayout->insertWidget( 0, m_toolBar );
- m_toolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
+//#ifdef Q_WS_X11
+// ui->stackedWidget->setContentsMargins( 4, 4, 4, 4 );
+//#else
+// ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 );
+//#endif
+ m_advancedWidgetUi->checkBoxReporter->setChecked( s->crashReporterEnabled() );
+ m_advancedWidgetUi->checkBoxHttp->setChecked( s->httpEnabled() );
//Network settings
TomahawkSettings::ExternalAddressMode mode = TomahawkSettings::instance()->externalAddressMode();
if ( mode == TomahawkSettings::Lan )
- ui->lanOnlyRadioButton->setChecked( true );
+ m_advancedWidgetUi->lanOnlyRadioButton->setChecked( true );
else if ( mode == TomahawkSettings::Static )
- ui->staticIpRadioButton->setChecked( true );
+ m_advancedWidgetUi->staticIpRadioButton->setChecked( true );
else
- ui->upnpRadioButton->setChecked( true );
+ m_advancedWidgetUi->upnpRadioButton->setChecked( true );
- ui->staticHostNamePortLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticHostName->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticPort->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticHostNameLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticPortLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostNamePortLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostName->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticPort->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostNameLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticPortLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
bool useProxy = TomahawkSettings::instance()->proxyType() == QNetworkProxy::Socks5Proxy;
- ui->enableProxyCheckBox->setChecked( useProxy );
- ui->proxyButton->setEnabled( useProxy );
+ m_advancedWidgetUi->enableProxyCheckBox->setChecked( useProxy );
+ m_advancedWidgetUi->proxyButton->setEnabled( useProxy );
- ui->aclEntryClearButton->setEnabled( TomahawkSettings::instance()->aclEntries().size() > 0 );
- connect( ui->aclEntryClearButton, SIGNAL( clicked( bool ) ), this, SLOT( aclEntryClearButtonClicked() ) );
+ m_advancedWidgetUi->aclEntryClearButton->setEnabled( TomahawkSettings::instance()->aclEntries().size() > 0 );
+ connect( m_advancedWidgetUi->aclEntryClearButton, SIGNAL( clicked( bool ) ), this, SLOT( aclEntryClearButtonClicked() ) );
- createIcons();
-#ifdef Q_WS_X11
- setContentsMargins( 4, 4, 4, 4 );
-#elif defined( Q_OS_MAC )
- setContentsMargins( 0, 0, 0, 4 );
-#else
- setContentsMargins( 0, 4, 4, 4 );
-#endif
+//#ifdef Q_WS_X11
+// setContentsMargins( 4, 4, 4, 4 );
+//#elif defined( Q_OS_MAC )
+// setContentsMargins( 0, 0, 0, 4 );
+//#else
+// setContentsMargins( 0, 4, 4, 4 );
+//#endif
#ifdef Q_WS_MAC
// Avoid resize handles on sheets on osx
@@ -132,14 +135,14 @@ SettingsDialog::SettingsDialog( QWidget *parent )
// Accounts
AccountDelegate* accountDelegate = new AccountDelegate( this );
- ui->accountsView->setItemDelegate( accountDelegate );
- ui->accountsView->setContextMenuPolicy( Qt::CustomContextMenu );
- ui->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
- ui->accountsView->setMouseTracking( true );
+ m_accountsWidgetUi->accountsView->setItemDelegate( accountDelegate );
+ m_accountsWidgetUi->accountsView->setContextMenuPolicy( Qt::CustomContextMenu );
+ m_accountsWidgetUi->accountsView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
+ m_accountsWidgetUi->accountsView->setMouseTracking( true );
connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::Account* ) ), this, SLOT( openAccountConfig( Tomahawk::Accounts::Account* ) ) );
connect( accountDelegate, SIGNAL( openConfig( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( openAccountFactoryConfig( Tomahawk::Accounts::AccountFactory* ) ) );
- connect( accountDelegate, SIGNAL( update( QModelIndex ) ), ui->accountsView, SLOT( update( QModelIndex ) ) );
+ connect( accountDelegate, SIGNAL( update( QModelIndex ) ), m_accountsWidgetUi->accountsView, SLOT( update( QModelIndex ) ) );
m_accountModel = new AccountModel( this );
m_accountProxy = new AccountModelFilterProxy( m_accountModel );
@@ -150,58 +153,58 @@ SettingsDialog::SettingsDialog( QWidget *parent )
connect( m_accountProxy, SIGNAL( errorInstalling( QPersistentModelIndex ) ), accountDelegate, SLOT( errorInstalling(QPersistentModelIndex) ) );
connect( m_accountProxy, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( scrollTo( QModelIndex ) ) );
- ui->accountsView->setModel( m_accountProxy );
+ m_accountsWidgetUi->accountsView->setModel( m_accountProxy );
- connect( ui->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) );
+ connect( m_accountsWidgetUi->installFromFileBtn, SIGNAL( clicked( bool ) ), this, SLOT( installFromFile() ) );
connect( m_accountModel, SIGNAL( createAccount( Tomahawk::Accounts::AccountFactory* ) ), this, SLOT( createAccountFromFactory( Tomahawk::Accounts::AccountFactory* ) ) );
- ui->accountsFilterCombo->addItem( tr( "All" ), Accounts::NoType );
- ui->accountsFilterCombo->addItem( accountTypeToString( SipType ), SipType );
- ui->accountsFilterCombo->addItem( accountTypeToString( ResolverType ), ResolverType );
- ui->accountsFilterCombo->addItem( accountTypeToString( StatusPushType ), StatusPushType );
+ m_accountsWidgetUi->accountsFilterCombo->addItem( tr( "All" ), Accounts::NoType );
+ m_accountsWidgetUi->accountsFilterCombo->addItem( accountTypeToString( SipType ), SipType );
+ m_accountsWidgetUi->accountsFilterCombo->addItem( accountTypeToString( ResolverType ), ResolverType );
+ m_accountsWidgetUi->accountsFilterCombo->addItem( accountTypeToString( StatusPushType ), StatusPushType );
- connect( ui->accountsFilterCombo, SIGNAL( activated( int ) ), this, SLOT( accountsFilterChanged( int ) ) );
+ connect( m_accountsWidgetUi->accountsFilterCombo, SIGNAL( activated( int ) ), this, SLOT( accountsFilterChanged( int ) ) );
if ( !Servent::instance()->isReady() )
{
- m_sipSpinner = new AnimatedSpinner( ui->accountsView );
+ m_sipSpinner = new AnimatedSpinner( m_accountsWidgetUi->accountsView );
m_sipSpinner->fadeIn();
connect( Servent::instance(), SIGNAL( ready() ), this, SLOT( serventReady() ) );
}
// ADVANCED
- ui->staticHostName->setText( s->externalHostname() );
- ui->staticPort->setValue( s->externalPort() );
- ui->proxyButton->setVisible( true );
+ m_advancedWidgetUi->staticHostName->setText( s->externalHostname() );
+ m_advancedWidgetUi->staticPort->setValue( s->externalPort() );
+ m_advancedWidgetUi->proxyButton->setVisible( true );
- ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
- ui->scannerTimeSpinBox->setValue( s->scannerTime() );
- ui->enableEchonestCatalog->setChecked( s->enableEchonestCatalogs() );
+ m_collectionWidgetUi->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
+ m_collectionWidgetUi->scannerTimeSpinBox->setValue( s->scannerTime() );
+ m_collectionWidgetUi->enableEchonestCatalog->setChecked( s->enableEchonestCatalogs() );
- connect( ui->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
+ connect( m_collectionWidgetUi->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
- if ( ui->checkBoxWatchForChanges->isChecked() )
+ if ( m_collectionWidgetUi->checkBoxWatchForChanges->isChecked() )
{
- ui->scanTimeLabel->show();
- ui->scannerTimeSpinBox->show();
+ m_collectionWidgetUi->scanTimeLabel->show();
+ m_collectionWidgetUi->scannerTimeSpinBox->show();
}
else
{
- ui->scanTimeLabel->hide();
- ui->scannerTimeSpinBox->hide();
+ m_collectionWidgetUi->scanTimeLabel->hide();
+ m_collectionWidgetUi->scannerTimeSpinBox->hide();
}
foreach ( const QString& dir, TomahawkSettings::instance()->scannerPaths() )
{
- ui->dirTree->checkPath( dir, Qt::Checked );
+ m_collectionWidgetUi->dirTree->checkPath( dir, Qt::Checked );
}
- ui->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() );
+// m_collectionWidgetUi->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() );
- int buttonsWidth = qMax( ui->proxyButton->sizeHint().width(),
- ui->aclEntryClearButton->sizeHint().width() );
- ui->proxyButton->setFixedWidth( buttonsWidth );
- ui->aclEntryClearButton->setFixedWidth( buttonsWidth );
+ int buttonsWidth = qMax( m_advancedWidgetUi->proxyButton->sizeHint().width(),
+ m_advancedWidgetUi->aclEntryClearButton->sizeHint().width() );
+ m_advancedWidgetUi->proxyButton->setFixedWidth( buttonsWidth );
+ m_advancedWidgetUi->aclEntryClearButton->setFixedWidth( buttonsWidth );
// NOW PLAYING
@@ -211,15 +214,30 @@ SettingsDialog::SettingsDialog( QWidget *parent )
// ui->checkBoxEnableAdium->hide();
// #endif
- connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) );
- connect( ui->lanOnlyRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
- connect( ui->staticIpRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
- connect( ui->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
- connect( ui->lanOnlyRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
- connect( ui->staticIpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
- connect( ui->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
- connect( ui->enableProxyCheckBox, SIGNAL( toggled(bool) ), SLOT( toggleProxyEnabled() ) );
- connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) );
+ m_dialog->addTab( m_accountsWidget, QPixmap( RESPATH "images/account-settings.png" ), tr( "Services" ), tr( "Services
"
+ "Configure the accounts and services used by Tomahawk "
+ "to search and retrieve music, find your friends and "
+ "update your status." ));
+
+ m_dialog->addTab( m_collectionWidget, QPixmap( RESPATH "images/music-settings.png" ), tr( "Collection" ), tr("Collection
"
+ "Manage how Tomahawk finds music on your computer." ));
+
+ m_dialog->addTab( m_advancedWidget, QPixmap( RESPATH "images/advanced-settings.png" ), tr( "Advanced" ), tr( "Advanced
"
+ "Configure Tomahawk's advanced settings, including "
+ "network connectivity settings, browser interaction "
+ "and more." ));
+
+ m_dialog->setCurrentIndex( 0 );
+
+ connect( m_advancedWidgetUi->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) );
+ connect( m_advancedWidgetUi->lanOnlyRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
+ connect( m_advancedWidgetUi->staticIpRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
+ connect( m_advancedWidgetUi->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( requiresRestart() ) );
+ connect( m_advancedWidgetUi->lanOnlyRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
+ connect( m_advancedWidgetUi->staticIpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
+ connect( m_advancedWidgetUi->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) );
+ connect( m_advancedWidgetUi->enableProxyCheckBox, SIGNAL( toggled(bool) ), SLOT( toggleProxyEnabled() ) );
+// connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) );
}
@@ -231,18 +249,18 @@ SettingsDialog::~SettingsDialog()
{
TomahawkSettings* s = TomahawkSettings::instance();
- s->setCrashReporterEnabled( ui->checkBoxReporter->checkState() == Qt::Checked );
- s->setHttpEnabled( ui->checkBoxHttp->checkState() == Qt::Checked );
- s->setProxyType( ui->enableProxyCheckBox->isChecked() ? QNetworkProxy::Socks5Proxy : QNetworkProxy::NoProxy );
- s->setExternalAddressMode( ui->upnpRadioButton->isChecked() ? TomahawkSettings::Upnp : ( ui->lanOnlyRadioButton->isChecked() ? TomahawkSettings::Lan : TomahawkSettings::Static ) );
+ s->setCrashReporterEnabled( m_advancedWidgetUi->checkBoxReporter->checkState() == Qt::Checked );
+ s->setHttpEnabled( m_advancedWidgetUi->checkBoxHttp->checkState() == Qt::Checked );
+ s->setProxyType( m_advancedWidgetUi->enableProxyCheckBox->isChecked() ? QNetworkProxy::Socks5Proxy : QNetworkProxy::NoProxy );
+ s->setExternalAddressMode( m_advancedWidgetUi->upnpRadioButton->isChecked() ? TomahawkSettings::Upnp : ( m_advancedWidgetUi->lanOnlyRadioButton->isChecked() ? TomahawkSettings::Lan : TomahawkSettings::Static ) );
- s->setExternalHostname( ui->staticHostName->text() );
- s->setExternalPort( ui->staticPort->value() );
+ s->setExternalHostname( m_advancedWidgetUi->staticHostName->text() );
+ s->setExternalPort( m_advancedWidgetUi->staticPort->value() );
- s->setScannerPaths( ui->dirTree->getCheckedPaths() );
- s->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() );
- s->setScannerTime( ui->scannerTimeSpinBox->value() );
- s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() );
+ s->setScannerPaths( m_collectionWidgetUi->dirTree->getCheckedPaths() );
+ s->setWatchForChanges( m_collectionWidgetUi->checkBoxWatchForChanges->isChecked() );
+ s->setScannerTime( m_collectionWidgetUi->scannerTimeSpinBox->value() );
+ s->setEnableEchonestCatalogs( m_collectionWidgetUi->enableEchonestCatalog->isChecked() );
// s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
@@ -250,10 +268,10 @@ SettingsDialog::~SettingsDialog()
s->sync();
if ( m_restartRequired )
- QMessageBox::information( this, tr( "Information" ), tr( "Some changed settings will not take effect until Tomahawk is restarted" ) );
+ QMessageBox::information( 0, tr( "Information" ), tr( "Some changed settings will not take effect until Tomahawk is restarted" ) );
TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory();
- if ( !ui->enableProxyCheckBox->isChecked() )
+ if ( !m_advancedWidgetUi->enableProxyCheckBox->isChecked() )
{
tDebug() << Q_FUNC_INFO << "Got NoProxy selected";
proxyFactory->setProxy( QNetworkProxy::NoProxy );
@@ -273,10 +291,19 @@ SettingsDialog::~SettingsDialog()
else
qDebug() << "Settings dialog cancelled, NOT saving prefs.";
- delete ui;
+ m_accountsWidget->deleteLater();
+ m_collectionWidget->deleteLater();
+ m_advancedWidget->deleteLater();
+ m_dialog->deleteLater();
}
+void
+SettingsDialog::show()
+{
+ m_dialog->show();
+}
+
void
SettingsDialog::serventReady()
{
@@ -284,71 +311,15 @@ SettingsDialog::serventReady()
}
-void
-SettingsDialog::createIcons()
-{
- ensurePolished();
-
- m_settingsGroup = new QActionGroup( m_toolBar );
-
- QWidget *leftSpacer = new QWidget( m_toolBar );
- leftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
- m_toolBar->addWidget( leftSpacer );
-
- QAction *accountsAction = new QAction( QIcon( RESPATH "images/account-settings.png" ),
- tr( "Services" ),
- m_toolBar );
- accountsAction->setCheckable( true );
- accountsAction->setToolTip( tr( "Services
"
- "Configure the accounts and services used by Tomahawk "
- "to search and retrieve music, find your friends and "
- "update your status." ) );
- m_settingsGroup->addAction( accountsAction );
-
- QAction *musicAction = new QAction( QIcon( RESPATH "images/music-settings.png" ),
- tr( "Collection" ),
- m_toolBar );
- musicAction->setCheckable( true );
- musicAction->setToolTip( tr( "Collection
"
- "Manage how Tomahawk finds music on your computer." ) );
- m_settingsGroup->addAction( musicAction );
-
-
- QAction *advancedAction = new QAction( QIcon( RESPATH "images/advanced-settings.png" ),
- tr( "Advanced" ),
- m_toolBar );
- advancedAction->setCheckable( true );
- advancedAction->setToolTip( tr( "Advanced
"
- "Configure Tomahawk's advanced settings, including "
- "network connectivity settings, browser interaction "
- "and more." ) );
- m_settingsGroup->addAction( advancedAction );
-
- m_settingsGroup->setExclusive( true );
-
- m_toolBar->addActions( m_settingsGroup->actions() );
-
- QWidget *rightSpacer = new QWidget( m_toolBar );
- rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
- m_toolBar->addWidget( rightSpacer );
-
- connect( m_settingsGroup, SIGNAL( triggered( QAction * ) ),
- this, SLOT( changePage( QAction * ) ) );
-
- accountsAction->setChecked( true );
- changePage( accountsAction );
-}
-
-
-void
-SettingsDialog::changePage( QAction *action )
-{
- int index = m_settingsGroup->actions().indexOf( action );
- if( ui->stackedWidget->currentIndex() != index )
- {
- ui->stackedWidget->setCurrentIndex( index );
- }
-}
+//void
+//SettingsDialog::changePage( QAction *action )
+//{
+// int index = m_settingsGroup->actions().indexOf( action );
+// if( ui->stackedWidget->currentIndex() != index )
+// {
+// ui->stackedWidget->setCurrentIndex( index );
+// }
+//}
void
@@ -361,11 +332,12 @@ SettingsDialog::onRejected()
void
SettingsDialog::changeEvent( QEvent *e )
{
- QDialog::changeEvent( e );
switch ( e->type() )
{
case QEvent::LanguageChange:
- ui->retranslateUi( this );
+ m_accountsWidgetUi->retranslateUi( m_accountsWidget );
+ m_collectionWidgetUi->retranslateUi( m_collectionWidget );
+ m_advancedWidgetUi->retranslateUi( m_advancedWidget );
break;
default:
@@ -386,33 +358,33 @@ SettingsDialog::showProxySettings()
void
SettingsDialog::toggleRemoteMode()
{
- ui->staticHostNamePortLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticHostName->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticPort->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticHostNameLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
- ui->staticPortLabel->setEnabled( ui->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostNamePortLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostName->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticPort->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticHostNameLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
+ m_advancedWidgetUi->staticPortLabel->setEnabled( m_advancedWidgetUi->staticIpRadioButton->isChecked() );
}
void
SettingsDialog::toggleProxyEnabled()
{
- ui->proxyButton->setEnabled( ui->enableProxyCheckBox->isChecked() );
+ m_advancedWidgetUi->proxyButton->setEnabled( m_advancedWidgetUi->enableProxyCheckBox->isChecked() );
}
void
SettingsDialog::updateScanOptionsView()
{
- if ( ui->checkBoxWatchForChanges->isChecked() )
+ if ( m_collectionWidgetUi->checkBoxWatchForChanges->isChecked() )
{
- ui->scanTimeLabel->show();
- ui->scannerTimeSpinBox->show();
+ m_collectionWidgetUi->scanTimeLabel->show();
+ m_collectionWidgetUi->scannerTimeSpinBox->show();
}
else
{
- ui->scanTimeLabel->hide();
- ui->scannerTimeSpinBox->hide();
+ m_collectionWidgetUi->scanTimeLabel->hide();
+ m_collectionWidgetUi->scannerTimeSpinBox->hide();
}
}
@@ -420,7 +392,7 @@ SettingsDialog::updateScanOptionsView()
void
SettingsDialog::accountsFilterChanged( int )
{
- AccountType filter = static_cast< AccountType >( ui->accountsFilterCombo->itemData( ui->accountsFilterCombo->currentIndex() ).toInt() );
+ AccountType filter = static_cast< AccountType >( m_accountsWidgetUi->accountsFilterCombo->itemData( m_accountsWidgetUi->accountsFilterCombo->currentIndex() ).toInt() );
m_accountProxy->setFilterType( filter );
}
@@ -451,7 +423,7 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory )
dialog.exec();
#else
// on osx a sheet needs to be non-modal
- AccountFactoryWrapper* dialog = new AccountFactoryWrapper( factory, this );
+ AccountFactoryWrapper* dialog = new AccountFactoryWrapper( factory, 0 );
dialog->show();
#endif
}
@@ -460,21 +432,21 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory )
void
SettingsDialog::createAccountFromFactory( AccountFactory* factory )
{
- TomahawkUtils::createAccountFromFactory( factory, this );
+ TomahawkUtils::createAccountFromFactory( factory, 0 );
}
void
SettingsDialog::openAccountConfig( Account* account, bool showDelete )
{
- TomahawkUtils::openAccountConfig( account, this, showDelete );
+ TomahawkUtils::openAccountConfig( account, 0, showDelete );
}
void
SettingsDialog::installFromFile()
{
- const QString resolver = QFileDialog::getOpenFileName( this, tr( "Install resolver from file" ), TomahawkSettings::instance()->scriptDefaultPath() );
+ const QString resolver = QFileDialog::getOpenFileName( 0, tr( "Install resolver from file" ), TomahawkSettings::instance()->scriptDefaultPath() );
if( !resolver.isEmpty() )
{
@@ -520,7 +492,7 @@ void
SettingsDialog::aclEntryClearButtonClicked()
{
QMessageBox::StandardButton button = QMessageBox::question(
- ui->stackedWidget,
+ 0,
tr( "Delete all Access Control entries?" ),
tr( "Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to." ),
QMessageBox::Ok | QMessageBox::Cancel,
@@ -529,7 +501,7 @@ SettingsDialog::aclEntryClearButtonClicked()
if ( button == QMessageBox::Ok )
{
ACLRegistry::instance()->wipeEntries();
- ui->aclEntryClearButton->setEnabled( false );
+ m_advancedWidgetUi->aclEntryClearButton->setEnabled( false );
}
}
@@ -537,7 +509,7 @@ SettingsDialog::aclEntryClearButtonClicked()
void
SettingsDialog::scrollTo( const QModelIndex& idx )
{
- ui->accountsView->scrollTo( idx, QAbstractItemView::PositionAtBottom );
+ m_accountsWidgetUi->accountsView->scrollTo( idx, QAbstractItemView::PositionAtBottom );
}
diff --git a/src/SettingsDialog.h b/src/SettingsDialog.h
index 88cb934a0..e9d9f8032 100644
--- a/src/SettingsDialog.h
+++ b/src/SettingsDialog.h
@@ -31,14 +31,16 @@
class AnimatedSpinner;
class QListWidgetItem;
-class Ui_StackedSettingsDialog;
+class Ui_Settings_Accounts;
+class Ui_Settings_Collection;
+class Ui_Settings_Advanced;
class SipPlugin;
class ResolversModel;
class QNetworkReply;
+class QToolbarTabDialog;
namespace Ui
{
- class SettingsDialog;
class ProxyDialog;
}
@@ -68,14 +70,15 @@ private:
Ui::ProxyDialog* ui;
};
-class SettingsDialog : public QDialog
+class SettingsDialog : public QObject
{
Q_OBJECT
public:
- explicit SettingsDialog( QWidget* parent = 0 );
+ explicit SettingsDialog( QObject* parent = 0 );
~SettingsDialog();
+ void show();
protected:
void changeEvent( QEvent* e );
@@ -97,7 +100,6 @@ private slots:
void updateScanOptionsView();
- void changePage( QAction *action );
void serventReady();
void aclEntryClearButtonClicked();
@@ -107,10 +109,16 @@ private slots:
private:
void createIcons();
- Ui_StackedSettingsDialog* ui;
+ Ui_Settings_Accounts* m_accountsWidgetUi;
+ QWidget* m_accountsWidget;
- QToolBar *m_toolBar;
- QActionGroup *m_settingsGroup;
+ Ui_Settings_Collection* m_collectionWidgetUi;
+ QWidget* m_collectionWidget;
+
+ Ui_Settings_Advanced* m_advancedWidgetUi;
+ QWidget* m_advancedWidget;
+
+ QToolbarTabDialog* m_dialog;
ProxyDialog m_proxySettings;
bool m_rejected;
diff --git a/src/Settings_Accounts.ui b/src/Settings_Accounts.ui
new file mode 100644
index 000000000..b7382c1c5
--- /dev/null
+++ b/src/Settings_Accounts.ui
@@ -0,0 +1,62 @@
+
+
+ Settings_Accounts
+
+
+
+ 0
+ 0
+ 508
+ 476
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ Install from file...
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Filter by capability:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+
+
+
diff --git a/src/Settings_Advanced.ui b/src/Settings_Advanced.ui
new file mode 100644
index 000000000..c13f79b25
--- /dev/null
+++ b/src/Settings_Advanced.ui
@@ -0,0 +1,262 @@
+
+
+ Settings_Advanced
+
+
+
+ 0
+ 0
+ 469
+ 475
+
+
+
+ Form
+
+
+ -
+
+
+ Remote Peer Connection Method
+
+
+
-
+
+
+ None (outgoing connections only)
+
+
+
+ -
+
+
+ Use UPnP to establish port forward (recommended)
+
+
+
+ -
+
+
+ Use static external IP address/host name and port
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Set this to your external IP address or host name. Make sure to forward the port to this host!
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Static Host Name:
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Static Port:
+
+
+
+ -
+
+
+ 65535
+
+
+ 50210
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+ SOCKS Proxy
+
+
+
-
+
+
+ Use SOCKS Proxy
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Proxy Settings...
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+ Other Settings
+
+
+
-
+
+
+ Qt::LeftToRight
+
+
+ Allow web browsers to interact with Tomahawk (recommended)
+
+
+ true
+
+
+
+ -
+
+
+ Qt::LeftToRight
+
+
+ Send reports after Tomahawk crashed
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Clear All Access Control Entries
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 13
+
+
+
+
+
+
+
+
+
diff --git a/src/Settings_Collection.ui b/src/Settings_Collection.ui
new file mode 100644
index 000000000..3031f1dd8
--- /dev/null
+++ b/src/Settings_Collection.ui
@@ -0,0 +1,93 @@
+
+
+ Settings_Collection
+
+
+
+ 0
+ 0
+ 423
+ 388
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ Path to scan for music files:
+
+
+
+ -
+
+
+
+
+ -
+
+
-
+
+
+ The Echo Nest supports keeping track of your catalog metadata
+ and using it to craft personalized radios. Enabling this option
+ will allow you (and all your friends) to create automatic playlists
+ and stations based on your personal taste profile.
+
+
+ Upload collection list to The Echo Nest to enable user radio
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Watch for changes
+
+
+
+ -
+
+
-
+
+
+ Time between scans, in seconds:
+
+
+
+ -
+
+
+ 60
+
+
+ 999999999
+
+
+
+
+
+
+
+
+
+
+
+ CheckDirTree
+ QTreeView
+
+
+
+
+
+
diff --git a/src/StackedSettingsDialog.ui b/src/StackedSettingsDialog.ui
index af3cfe49d..0377d15dd 100644
--- a/src/StackedSettingsDialog.ui
+++ b/src/StackedSettingsDialog.ui
@@ -6,8 +6,8 @@
0
0
- 655
- 500
+ 692
+ 604
@@ -22,7 +22,7 @@
-
- 0
+ 1
@@ -461,6 +461,12 @@
+ buttonBox
+
+ frame_4
+ frame_2
+ frameNetworkAdvanced
+ stackedWidget
diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp
index 22dcdd22a..30491c261 100644
--- a/src/TomahawkWindow.cpp
+++ b/src/TomahawkWindow.cpp
@@ -810,7 +810,7 @@ void
TomahawkWindow::showSettingsDialog()
{
SettingsDialog win;
- win.exec();
+ win.show();
}
diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt
index c148deb59..c59e804f3 100644
--- a/src/libtomahawk/CMakeLists.txt
+++ b/src/libtomahawk/CMakeLists.txt
@@ -392,6 +392,7 @@ IF( APPLE )
utils/TomahawkUtils_Mac.mm
mac/FileHelpers.mm
thirdparty/Qocoa/qsearchfield_mac.mm
+ thirdparty/Qocoa/qtoolbartabdialog_mac.mm
widgets/SourceTreePopupDialog_mac.mm )
SET_SOURCE_FILES_PROPERTIES(utils/TomahawkUtils_Mac.mm PROPERTIES COMPILE_FLAGS "-fvisibility=default")
@@ -408,7 +409,7 @@ IF( APPLE )
/System/Library/Frameworks/Security.framework
)
ELSE( APPLE )
- SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp )
+ SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp )
ENDIF( APPLE )
IF(LIBLASTFM_FOUND)
diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp
index 6a8c98b63..9d985f156 100644
--- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp
+++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp
@@ -294,7 +294,7 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply )
m_ui->progressBar->setValue( thisPage );
foreach ( lastfm::XmlQuery e, loved.children( "track" ) )
{
-// tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt();
+ tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt();
Tomahawk::query_ptr query = Tomahawk::Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false );
if ( query.isNull() )
continue;
@@ -336,6 +336,8 @@ LastFmConfig::onLovedFinished( QNetworkReply* reply )
bool trackEquality( const Tomahawk::query_ptr& first, const Tomahawk::query_ptr& second )
{
+ qDebug() << "Comparing:" << first->track() << second->track();
+ qDebug() << "==========" << first->artist() << second->artist();
return first->equals( second, true );
}
@@ -372,15 +374,20 @@ LastFmConfig::syncLoved()
foreach ( const Tomahawk::query_ptr& localLoved, myLoved )
{
+ qDebug() << "CHECKING FOR LOCAL LOVED ON LAST.FM TOO:" << m_localLoved[ localLoved ].value.toString() << localLoved->track() << localLoved->artist();
QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( m_lastfmLoved.begin(), m_lastfmLoved.end(), boost::bind( &trackEquality, _1, boost::ref( localLoved ) ) );
+ qDebug() << "Result:" << (iter == m_lastfmLoved.constEnd());
// If we unloved it locally, but it's still loved on last.fm, unlove it
if ( m_localLoved[ localLoved ].value.toString() == "false" && iter != m_lastfmLoved.constEnd() )
lastFmToUnlove << localLoved;
// If we loved it locally but not loved on last.fm, love it
if ( m_localLoved[ localLoved ].value.toString() == "true" && iter == m_lastfmLoved.constEnd() )
+ {
+ qDebug() << "Found Local loved track but not on last.fm!:" << localLoved->track() << localLoved->artist();
lastFmToLove << localLoved;
+ }
}
foreach ( const Tomahawk::query_ptr& track, localToLove )
diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h
new file mode 100644
index 000000000..3949bd6f9
--- /dev/null
+++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h
@@ -0,0 +1,48 @@
+#ifndef QTOOLBARTABWIDGET_H
+#define QTOOLBARTABWIDGET_H
+
+#include
+#include
+#include
+
+#include "DllMacro.h"
+
+class QToolbarTabDialogPrivate;
+
+class QAction;
+
+/**
+ Dialog with a toolbar that behaves like a tab widget.
+
+ Note that on OS X there are no OK/Cancel buttons, every setting should be applied immediately.
+ The accepted() signal will be emitted on close/hide regardless.
+ */
+class DLLEXPORT QToolbarTabDialog : public QObject
+{
+ Q_OBJECT
+public:
+ QToolbarTabDialog();
+ virtual ~QToolbarTabDialog();
+
+ /*
+ * If the given widget has a QSizePolicy of Fixed in either direction, the dialog will not be resizable in that
+ * direction.
+ */
+ void addTab(QWidget* page, const QPixmap& icon, const QString& label, const QString& tooltip = QString());
+
+ void setCurrentIndex(int index);
+
+ void show();
+ void hide();
+
+Q_SIGNALS:
+ void accepted();
+ void rejected();
+
+private:
+ QScopedPointer pimpl;
+
+ friend class ::QToolbarTabDialogPrivate;
+};
+
+#endif // QTOOLBARTABWIDGET_H
diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm
new file mode 100644
index 000000000..e36a1f15e
--- /dev/null
+++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm
@@ -0,0 +1,448 @@
+/*
+ Copyright (C) 2012 by Leo Franchi
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+#include "qtoolbartabdialog.h"
+#include "moc_qtoolbartabdialog.cpp"
+
+#include "qocoa_mac.h"
+
+#import
+#import
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct ItemData {
+ QPixmap icon;
+ QString text, tooltip;
+ QMacNativeWidget* nativeWidget;
+ QWidget* page;
+};
+
+
+namespace {
+
+static const int TOOLBAR_ITEM_WIDTH = 32;
+
+CGFloat ToolbarHeightForWindow(NSWindow *window)
+{
+ CGFloat toolbarHeight = 0.0f;
+
+ NSToolbar *toolbar = toolbar = [window toolbar];
+
+ if(toolbar && [toolbar isVisible])
+ {
+ NSRect windowFrame = [NSWindow contentRectForFrameRect:[window frame]
+ styleMask:[window styleMask]];
+ toolbarHeight = NSHeight(windowFrame) - NSHeight([[window contentView] frame]);
+ }
+
+ return toolbarHeight;
+}
+
+};
+
+@interface ToolbarDelegate : NSObject
+{
+ QToolbarTabDialogPrivate *pimpl;
+}
+// Internal
+-(void)setPrivate:(QToolbarTabDialogPrivate*)withPimpl;
+
+// NSToolbarItem action
+-(void)changePanes:(id)sender;
+
+// NSToolbarDelegate
+-(NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted;
+-(NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar;
+-(NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar;
+-(NSArray*) toolbarSelectableItemIdentifiers: (NSToolbar*)toolbar;
+
+// NSWindowDelegate
+-(NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize;
+-(void)windowWillClose:(NSNotification *)notification;
+@end
+
+class QToolbarTabDialogPrivate {
+public:
+ QToolbarTabDialogPrivate(QToolbarTabDialog* dialog) : q(dialog),
+ currentPane(NULL),
+ minimumWidthForToolbar(0)
+ {
+ }
+
+ ~QToolbarTabDialogPrivate() {
+ // unset the delegate and toolbar from the window and manually release them
+ // otherwise, for some reason the old delegate is laying around when we
+ // create a new NSWindow
+ [[prefsWindow toolbar] setDelegate:NULL];
+ [prefsWindow setToolbar:NULL];
+ [prefsWindow release];
+ [toolBar release];
+ [toolBarDelegate release];
+ }
+
+ void calculateSize() {
+ NSRect windowFrame = [prefsWindow frame];
+
+ while ([[toolBar visibleItems] count] < [[toolBar items] count]) {
+ //Each toolbar item is 32x32; we expand by one toolbar item width repeatedly until they all fit
+ windowFrame.origin.x -= TOOLBAR_ITEM_WIDTH / 2;
+ windowFrame.size.width += TOOLBAR_ITEM_WIDTH / 2;
+
+ [prefsWindow setFrame:windowFrame display:NO];
+ [prefsWindow setMinSize: windowFrame.size];
+ }
+ minimumWidthForToolbar = windowFrame.size.width;
+ }
+
+ void showPaneWithIdentifier(NSString* ident) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ const QString identStr = toQString(ident);
+ Q_ASSERT(items.contains(identStr));
+ if (!items.contains(identStr))
+ return;
+
+ QWidget* newWidget = items[identStr].nativeWidget;
+ Q_ASSERT(newWidget);
+ if (!newWidget)
+ return;
+
+ QWidget* newPage = items[identStr].page;
+ Q_ASSERT(newPage);
+ if (!newPage)
+ return;
+
+ // Clear first responder on window and set a temporary NSView on the window
+ // while we change the widget out underneath
+ [prefsWindow makeFirstResponder:nil];
+
+ NSView *tempView = [[NSView alloc] initWithFrame:[[prefsWindow contentView] frame]];
+ [prefsWindow setContentView:tempView];
+ [tempView release];
+
+ QSize sizeToUse = newPage->sizeHint().isNull() ? newPage->size() : newPage->sizeHint();
+
+ static const int spacing = 4;
+
+ [prefsWindow setMinSize:NSMakeSize(sizeToUse.width(), sizeToUse.height())];
+
+ // Make room for the new view
+ NSRect newFrame = [prefsWindow frame];
+ newFrame.size.height = sizeToUse.height() + ([prefsWindow frame].size.height - [[prefsWindow contentView] frame].size.height) + spacing;
+ newFrame.size.width = sizeToUse.width() + spacing;
+
+ //Ensure the full toolbar still fits
+ if (newFrame.size.width < minimumWidthForToolbar) newFrame.size.width = minimumWidthForToolbar;
+
+ // Preserve upper left point of window during resize.
+ newFrame.origin.y += ([[prefsWindow contentView] frame].size.height - sizeToUse.height()) - spacing;
+
+ [prefsWindow setFrame:newFrame display:YES animate:YES];
+
+ [prefsWindow setContentView: [panes objectForKey:ident]];
+ currentPane = ident;
+
+ // Resize the Qt widget immediately as well
+ resizeCurrentPageToSize([[prefsWindow contentView] frame].size);
+
+ NSSize minSize = [prefsWindow frame].size;
+ minSize.height -= ToolbarHeightForWindow(prefsWindow);
+
+ [prefsWindow setMinSize:minSize];
+
+ BOOL canResize = YES;
+ NSSize maxSize = NSMakeSize(FLT_MAX, FLT_MAX);
+
+ if (newPage->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed) {
+ canResize = NO;
+ maxSize.width = minSize.width;
+ }
+ if (newPage->sizePolicy().verticalPolicy() == QSizePolicy::Fixed) {
+ canResize = NO;
+ maxSize.height = minSize.height;
+ }
+
+
+ [prefsWindow setMaxSize:maxSize];
+ [prefsWindow setShowsResizeIndicator:canResize];
+
+ [prefsWindow setTitle:ident];
+
+ [pool drain];
+ }
+
+ void resizeCurrentPageToSize(NSSize frameSize) {
+ const QString curPane = toQString(currentPane);
+ if (items.contains(curPane) && items[curPane].nativeWidget) {
+ items[curPane].nativeWidget->resize(frameSize.width, frameSize.height);
+ }
+ }
+
+ void emitAccepted() {
+ if (q.isNull())
+ return;
+
+ q.data()->accepted();
+ }
+
+ QWeakPointer q;
+
+ NSWindow* prefsWindow;
+ ToolbarDelegate *toolBarDelegate;
+ QMap items;
+
+ NSMutableDictionary *panes;
+ NSToolbar *toolBar;
+ NSString* currentPane;
+
+ int minimumWidthForToolbar;
+};
+
+
+@implementation ToolbarDelegate
+
+-(id) init {
+ if( self = [super init] )
+ {
+ pimpl = nil;
+ }
+
+ return self;
+}
+
+-(void) setPrivate:(QToolbarTabDialogPrivate *)withPimpl
+{
+ pimpl = withPimpl;
+}
+
+-(void)changePanes:(id)sender
+{
+ Q_UNUSED(sender);
+ if (!pimpl)
+ return;
+
+ pimpl->showPaneWithIdentifier([pimpl->toolBar selectedItemIdentifier]);
+}
+
+-(NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted
+{
+ Q_UNUSED(toolbar);
+ Q_UNUSED(willBeInserted);
+ if (!pimpl)
+ return nil;
+
+ NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease];
+ const QString identQStr = toQString(itemIdent);
+ if (pimpl->items.contains(identQStr))
+ {
+ const ItemData& data = pimpl->items[identQStr];
+ NSString* label = fromQString(data.text);
+
+ [toolbarItem setLabel:label];
+ [toolbarItem setPaletteLabel:label];
+
+ [toolbarItem setToolTip:fromQString(data.tooltip)];
+ [toolbarItem setImage:fromQPixmap(data.icon)];
+
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector(changePanes:)];
+
+ } else {
+ toolbarItem = nil;
+ }
+
+ return toolbarItem;
+}
+
+-(NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
+{
+ Q_UNUSED(toolbar);
+ if (!pimpl)
+ return [NSArray array];
+
+ NSMutableArray* allowedItems = [[[NSMutableArray alloc] init] autorelease];
+
+ Q_FOREACH( const QString& identQStr, pimpl->items.keys())
+ [allowedItems addObject:fromQString(identQStr)];
+
+ [allowedItems addObjectsFromArray:[NSArray arrayWithObjects:NSToolbarSeparatorItemIdentifier,
+ NSToolbarSpaceItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
+ NSToolbarCustomizeToolbarItemIdentifier, nil] ];
+
+ return allowedItems;
+}
+
+
+-(NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
+{
+ Q_UNUSED(toolbar);
+ if (!pimpl)
+ return [NSArray array];
+
+ return [[[NSMutableArray alloc] initWithArray:[pimpl->panes allKeys]] autorelease];
+
+}
+
+
+-(NSArray*) toolbarSelectableItemIdentifiers: (NSToolbar*)toolbar
+{
+ Q_UNUSED(toolbar);
+ if (!pimpl)
+ return [NSArray array];
+
+ return [[[NSMutableArray alloc] initWithArray:[pimpl->panes allKeys]] autorelease];
+}
+
+-(NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
+{
+ Q_UNUSED(sender);
+ if (!pimpl)
+ return frameSize;
+
+ pimpl->resizeCurrentPageToSize(frameSize);
+
+ return frameSize;
+}
+
+-(void)windowWillClose:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+
+ pimpl->emitAccepted();
+}
+@end
+
+QToolbarTabDialog::QToolbarTabDialog() :
+ QObject(0),
+ pimpl(new QToolbarTabDialogPrivate(this))
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ pimpl->panes = [[NSMutableDictionary alloc] init];
+
+ static const int defaultWidth = 350;
+ static const int defaultHeight = 200;
+ pimpl->prefsWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, defaultWidth, defaultHeight)
+ styleMask:NSClosableWindowMask | NSResizableWindowMask | NSTitledWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO];
+
+ [pimpl->prefsWindow setReleasedWhenClosed:NO];
+ [pimpl->prefsWindow setTitle:@"Preferences"];
+
+ // identifier is some app-unique string, since all toolbars in an app share state. make this unique to this app's preferences window
+ pimpl->toolBar = [[NSToolbar alloc] initWithIdentifier:[NSString stringWithFormat:@"%@.prefspanel.toolbar", fromQString(QCoreApplication::instance()->applicationName())]];
+ [pimpl->toolBar setAllowsUserCustomization: NO];
+ [pimpl->toolBar setAutosavesConfiguration: NO];
+ [pimpl->toolBar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
+
+ pimpl->toolBarDelegate = [[ToolbarDelegate alloc] init];
+ [pimpl->toolBarDelegate setPrivate:pimpl.data()];
+
+ [pimpl->prefsWindow setDelegate:pimpl->toolBarDelegate];
+ [pimpl->toolBar setDelegate:pimpl->toolBarDelegate];
+
+ [pimpl->prefsWindow setToolbar:pimpl->toolBar];
+
+ [pool drain];
+}
+
+QToolbarTabDialog::~QToolbarTabDialog()
+{
+}
+
+void QToolbarTabDialog::addTab(QWidget* page, const QPixmap& icon, const QString& label, const QString& tooltip)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSString* identifier = fromQString(label);
+
+ QMacNativeWidget* nativeWidget = new QMacNativeWidget;
+ nativeWidget->move(0, 0);
+ nativeWidget->setPalette(page->palette());
+ nativeWidget->setAutoFillBackground(true);
+
+ QVBoxLayout* l = new QVBoxLayout;
+ l->setContentsMargins(2, 2, 2, 2);
+ l->setSpacing(0);
+ page->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ l->addWidget(page);
+ nativeWidget->setLayout(l);
+
+ NSView *nativeView = reinterpret_cast(nativeWidget->winId());
+ [nativeView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ [nativeView setAutoresizesSubviews:YES];
+
+ nativeWidget->show();
+
+ ItemData data;
+ data.icon = icon;
+ data.text = label;
+ data.tooltip = tooltip;
+ data.nativeWidget = nativeWidget;
+ data.page = page;
+ pimpl->items.insert(label, data);
+
+ [pimpl->panes setObject:nativeView forKey:identifier];
+
+ pimpl->showPaneWithIdentifier(identifier);
+
+ [pimpl->toolBar insertItemWithItemIdentifier:identifier atIndex:[[pimpl->toolBar items] count]];
+ [pimpl->toolBar setSelectedItemIdentifier:identifier];
+ [[pimpl->prefsWindow standardWindowButton:NSWindowZoomButton] setEnabled:NO];
+
+ pimpl->calculateSize();
+ [pool drain];
+}
+
+
+void QToolbarTabDialog::setCurrentIndex(int index)
+{
+ Q_ASSERT(pimpl);
+ if (!pimpl)
+ return;
+
+ [pimpl->toolBar setSelectedItemIdentifier:[[[pimpl->toolBar items] objectAtIndex:index] itemIdentifier]];
+ pimpl->showPaneWithIdentifier([[[pimpl->toolBar items] objectAtIndex:index] itemIdentifier]);
+}
+
+void QToolbarTabDialog::show()
+{
+ [pimpl->prefsWindow makeKeyAndOrderFront:nil];
+}
+
+void QToolbarTabDialog::hide()
+{
+ Q_ASSERT(pimpl);
+ if (!pimpl)
+ return;
+
+ [pimpl->prefsWindow close];
+ emit accepted();
+}
+
diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp
new file mode 100644
index 000000000..08b998b4c
--- /dev/null
+++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp
@@ -0,0 +1,167 @@
+#include "qtoolbartabdialog.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class QToolbarTabDialogPrivate : public QObject {
+ Q_OBJECT
+public:
+ QToolbarTabDialogPrivate(QToolbarTabDialog* qq) : q(qq), layout(0), toolbar(0), rightSpacer(0), stack(0), separator(0), buttons(0), actionGroup(0) {}
+
+public slots:
+ void actionTriggered(QAction* action) {
+ if (dialog.isNull())
+ return;
+
+ const int idx = toolbar->actions().indexOf(action);
+ Q_ASSERT(idx > -1);
+ if (idx < 0)
+ return;
+
+ stack->setCurrentIndex(idx);
+ }
+
+ void accepted() {
+ Q_ASSERT(!dialog.isNull());
+ Q_ASSERT(!q.isNull());
+
+ dialog.data()->hide();
+ emit q.data()->accepted();
+ }
+
+ void rejected() {
+ Q_ASSERT(!dialog.isNull());
+ Q_ASSERT(!q.isNull());
+
+ dialog.data()->hide();
+ emit q.data()->rejected();
+ }
+
+public:
+ QWeakPointer dialog;
+ QWeakPointer q;
+
+ QVBoxLayout* layout;
+ QToolBar* toolbar;
+ QAction* rightSpacer;
+ QStackedWidget* stack;
+ QFrame* separator;
+ QDialogButtonBox* buttons;
+ QActionGroup* actionGroup;
+
+};
+
+QToolbarTabDialog::QToolbarTabDialog() :
+ QObject(0),
+ pimpl(new QToolbarTabDialogPrivate(this))
+{
+ pimpl->dialog = new QDialog;
+ pimpl->dialog.data()->setModal(true);
+
+ pimpl->toolbar = new QToolBar(pimpl->dialog.data());
+ pimpl->toolbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+
+ pimpl->stack = new QStackedWidget(pimpl->dialog.data());
+
+ pimpl->separator = new QFrame(pimpl->dialog.data());
+ pimpl->separator->setFrameShape(QFrame::HLine);
+ pimpl->separator->setFrameShadow(QFrame::Sunken);
+
+ pimpl->actionGroup = new QActionGroup(pimpl->dialog.data());
+
+ connect(pimpl->toolbar, SIGNAL(actionTriggered(QAction*)), pimpl.data(), SLOT(actionTriggered(QAction*)));
+
+ pimpl->buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, pimpl->dialog.data());
+ connect(pimpl->buttons, SIGNAL(accepted()), pimpl->dialog.data(), SLOT(accept()));
+ connect(pimpl->buttons, SIGNAL(rejected()), pimpl->dialog.data(), SLOT(reject()));
+
+ connect(pimpl->dialog.data(), SIGNAL(accepted()), pimpl.data(), SLOT(accepted()));
+ connect(pimpl->dialog.data(), SIGNAL(rejected()), pimpl.data(), SLOT(rejected()));
+
+ QWidget* leftSpacer = new QWidget(pimpl->toolbar);
+ leftSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ QWidget* rightSpacer = new QWidget(pimpl->toolbar);
+ rightSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+
+ pimpl->toolbar->addWidget(leftSpacer);
+ pimpl->rightSpacer = pimpl->toolbar->addWidget(rightSpacer);
+
+ pimpl->layout = new QVBoxLayout;
+ pimpl->layout->addWidget(pimpl->toolbar);
+ pimpl->layout->addWidget(pimpl->separator);
+ pimpl->layout->addWidget(pimpl->stack);
+ pimpl->layout->addWidget(pimpl->buttons);
+ pimpl->dialog.data()->setLayout(pimpl->layout);
+}
+
+QToolbarTabDialog::~QToolbarTabDialog()
+{
+ if (pimpl && !pimpl->dialog.isNull()) {
+ delete pimpl->dialog.data();
+ }
+}
+
+void QToolbarTabDialog::addTab(QWidget* page, const QPixmap& icon, const QString& label, const QString& tooltip)
+{
+ Q_ASSERT(pimpl);
+ if (!pimpl)
+ return;
+
+ pimpl->toolbar->removeAction(pimpl->rightSpacer);
+
+ QAction* action = new QAction(icon, label, pimpl->toolbar);
+ action->setCheckable(true);
+ action->setToolTip(tooltip);
+
+ pimpl->actionGroup->addAction(action);
+
+ pimpl->toolbar->addAction(action);
+ pimpl->stack->addWidget(page);
+
+ pimpl->toolbar->addAction(pimpl->rightSpacer);
+}
+
+void QToolbarTabDialog::setCurrentIndex(int index)
+{
+ Q_ASSERT(pimpl);
+ if (!pimpl || pimpl->dialog.isNull())
+ return;
+
+
+ Q_ASSERT(index < pimpl->toolbar->actions().length());
+ Q_ASSERT(index < pimpl->stack->count());
+ if (index < 0 || index > pimpl->toolbar->actions().length())
+ return;
+ if (index > pimpl->stack->count())
+ return;
+
+ if (pimpl->stack->currentIndex() != index)
+ pimpl->stack->setCurrentIndex(index);
+}
+
+void QToolbarTabDialog::show()
+{
+ Q_ASSERT(pimpl);
+ Q_ASSERT(!pimpl->dialog.isNull());
+ if (!pimpl || pimpl->dialog.isNull())
+ return;
+
+ pimpl->dialog.data()->show();
+}
+
+void QToolbarTabDialog::hide()
+{
+ Q_ASSERT(pimpl);
+ Q_ASSERT(!pimpl->dialog.isNull());
+ if (!pimpl || pimpl->dialog.isNull())
+ return;
+
+ pimpl->dialog.data()->hide();
+}
+
+#include "moc_qtoolbartabdialog_nonmac.cpp"