From fc712fba19f2c504fe4546138cb23eb77b045881 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 08:51:31 -0400 Subject: [PATCH 01/12] Initial refactor of settings dialog with Qocoa --- src/CMakeLists.txt | 4 +- src/SettingsDialog.cpp | 338 ++++++------- src/SettingsDialog.h | 24 +- src/Settings_Accounts.ui | 62 +++ src/Settings_Advanced.ui | 262 ++++++++++ src/Settings_Collection.ui | 93 ++++ src/StackedSettingsDialog.ui | 12 +- src/TomahawkWindow.cpp | 2 +- src/libtomahawk/CMakeLists.txt | 3 +- .../accounts/lastfm/LastFmConfig.cpp | 9 +- .../thirdparty/Qocoa/qtoolbartabdialog.h | 48 ++ .../thirdparty/Qocoa/qtoolbartabdialog_mac.mm | 448 ++++++++++++++++++ .../Qocoa/qtoolbartabdialog_nonmac.cpp | 167 +++++++ 13 files changed, 1274 insertions(+), 198 deletions(-) create mode 100644 src/Settings_Accounts.ui create mode 100644 src/Settings_Advanced.ui create mode 100644 src/Settings_Collection.ui create mode 100644 src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h create mode 100644 src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm create mode 100644 src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp 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 +
widgets/CheckDirTree.h
+
+
+ + +
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" From 8f86171130ad4b70ad35a6fba048cce53d7d08e0 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 16:08:49 -0400 Subject: [PATCH 02/12] Fix up non-mac with new qocoa widget --- src/SettingsDialog.cpp | 113 ++++++++---------- src/SettingsDialog.h | 7 +- src/TomahawkWindow.cpp | 7 +- src/TomahawkWindow.h | 2 + src/libtomahawk/CMakeLists.txt | 2 +- ...ialog_nonmac.cpp => qtoolbartabdialog.cpp} | 16 ++- src/sourcetree/SourceTreeView.cpp | 2 + 7 files changed, 77 insertions(+), 72 deletions(-) rename src/libtomahawk/thirdparty/Qocoa/{qtoolbartabdialog_nonmac.cpp => qtoolbartabdialog.cpp} (91%) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 4aafe6386..e04908a44 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -237,60 +237,62 @@ SettingsDialog::SettingsDialog(QObject *parent ) 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() ) ); + + connect( m_dialog, SIGNAL( accepted() ), SLOT( saveSettings() ) ); + connect( m_dialog, SIGNAL( rejected() ), SLOT( onRejected() ) ); +} + + +void +SettingsDialog::saveSettings() +{ + qDebug() << Q_FUNC_INFO; + + TomahawkSettings* s = TomahawkSettings::instance(); + + 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( m_advancedWidgetUi->staticHostName->text() ); + s->setExternalPort( m_advancedWidgetUi->staticPort->value() ); + + 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() ); + + s->applyChanges(); + s->sync(); + + if ( m_restartRequired ) + QMessageBox::information( 0, tr( "Information" ), tr( "Some changed settings will not take effect until Tomahawk is restarted" ) ); + + TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory(); + if ( !m_advancedWidgetUi->enableProxyCheckBox->isChecked() ) + { + tDebug() << Q_FUNC_INFO << "Got NoProxy selected"; + proxyFactory->setProxy( QNetworkProxy::NoProxy ); + } + else + { + tDebug() << Q_FUNC_INFO << "Got Socks5Proxy selected"; + proxyFactory->setProxy( QNetworkProxy( QNetworkProxy::Socks5Proxy, s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() ) ); + if ( !s->proxyNoProxyHosts().isEmpty() ) + { + tDebug() << Q_FUNC_INFO << "noproxy hosts:" << s->proxyNoProxyHosts(); + tDebug() << Q_FUNC_INFO << "split noproxy line edit is " << s->proxyNoProxyHosts().split( ' ', QString::SkipEmptyParts ); + proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ' ', QString::SkipEmptyParts ) ); + } + } } SettingsDialog::~SettingsDialog() { - qDebug() << Q_FUNC_INFO; - - if ( !m_rejected ) - { - TomahawkSettings* s = TomahawkSettings::instance(); - - 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( m_advancedWidgetUi->staticHostName->text() ); - s->setExternalPort( m_advancedWidgetUi->staticPort->value() ); - - 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() ); - - s->applyChanges(); - s->sync(); - - if ( m_restartRequired ) - QMessageBox::information( 0, tr( "Information" ), tr( "Some changed settings will not take effect until Tomahawk is restarted" ) ); - - TomahawkUtils::NetworkProxyFactory* proxyFactory = TomahawkUtils::proxyFactory(); - if ( !m_advancedWidgetUi->enableProxyCheckBox->isChecked() ) - { - tDebug() << Q_FUNC_INFO << "Got NoProxy selected"; - proxyFactory->setProxy( QNetworkProxy::NoProxy ); - } - else - { - tDebug() << Q_FUNC_INFO << "Got Socks5Proxy selected"; - proxyFactory->setProxy( QNetworkProxy( QNetworkProxy::Socks5Proxy, s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() ) ); - if ( !s->proxyNoProxyHosts().isEmpty() ) - { - tDebug() << Q_FUNC_INFO << "noproxy hosts:" << s->proxyNoProxyHosts(); - tDebug() << Q_FUNC_INFO << "split noproxy line edit is " << s->proxyNoProxyHosts().split( ' ', QString::SkipEmptyParts ); - proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ' ', QString::SkipEmptyParts ) ); - } - } - } - else - qDebug() << "Settings dialog cancelled, NOT saving prefs."; - m_accountsWidget->deleteLater(); m_collectionWidget->deleteLater(); m_advancedWidget->deleteLater(); @@ -311,17 +313,6 @@ SettingsDialog::serventReady() } -//void -//SettingsDialog::changePage( QAction *action ) -//{ -// int index = m_settingsGroup->actions().indexOf( action ); -// if( ui->stackedWidget->currentIndex() != index ) -// { -// ui->stackedWidget->setCurrentIndex( index ); -// } -//} - - void SettingsDialog::onRejected() { @@ -417,7 +408,7 @@ SettingsDialog::openAccountFactoryConfig( AccountFactory* factory ) } #ifndef Q_OS_MAC - AccountFactoryWrapper dialog( factory, this ); + AccountFactoryWrapper dialog( factory, 0 ); QWeakPointer< AccountFactoryWrapper > watcher( &dialog ); dialog.exec(); diff --git a/src/SettingsDialog.h b/src/SettingsDialog.h index e9d9f8032..885997fde 100644 --- a/src/SettingsDialog.h +++ b/src/SettingsDialog.h @@ -103,12 +103,13 @@ private slots: void serventReady(); void aclEntryClearButtonClicked(); - + void requiresRestart(); -private: - void createIcons(); +private slots: + void saveSettings(); +private: Ui_Settings_Accounts* m_accountsWidgetUi; QWidget* m_accountsWidget; diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 30491c261..9adb2c6bc 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -100,6 +100,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) , m_searchWidget( 0 ) , m_audioControls( new AudioControls( this ) ) , m_trayIcon( new TomahawkTrayIcon( this ) ) + , m_settingsDialog( 0 ) , m_audioRetryCounter( 0 ) { setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) ); @@ -809,8 +810,10 @@ TomahawkWindow::onHistoryForwardAvailable( bool avail ) void TomahawkWindow::showSettingsDialog() { - SettingsDialog win; - win.show(); + if ( !m_settingsDialog ) + m_settingsDialog = new SettingsDialog; + + m_settingsDialog->show(); } diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 0b0f130c7..b51477780 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -37,6 +37,7 @@ #include #endif +class SettingsDialog; namespace Tomahawk { namespace Accounts @@ -184,6 +185,7 @@ private: QueueView* m_queueView; AnimatedSplitter* m_sidebar; JobStatusSortModel* m_jobsModel; + SettingsDialog* m_settingsDialog; // Menus and menu actions: Accounts menu QMenuBar *m_menuBar; diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index c59e804f3..7cb8b637a 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -409,7 +409,7 @@ IF( APPLE ) /System/Library/Frameworks/Security.framework ) ELSE( APPLE ) - SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp ) + SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp thirdparty/Qocoa/qtoolbartabdialog.cpp ) ENDIF( APPLE ) IF(LIBLASTFM_FOUND) diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp similarity index 91% rename from src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp rename to src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp index 08b998b4c..89d0b10a6 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_nonmac.cpp +++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp @@ -19,11 +19,12 @@ public slots: return; const int idx = toolbar->actions().indexOf(action); - Q_ASSERT(idx > -1); - if (idx < 0) + // There's a left spacer, so we want 1 less + Q_ASSERT(idx > 0); + if (idx < 1) return; - stack->setCurrentIndex(idx); + stack->setCurrentIndex(idx - 1); } void accepted() { @@ -133,7 +134,7 @@ void QToolbarTabDialog::setCurrentIndex(int index) return; - Q_ASSERT(index < pimpl->toolbar->actions().length()); + Q_ASSERT(index < pimpl->toolbar->actions().length() + 1); Q_ASSERT(index < pimpl->stack->count()); if (index < 0 || index > pimpl->toolbar->actions().length()) return; @@ -142,6 +143,11 @@ void QToolbarTabDialog::setCurrentIndex(int index) if (pimpl->stack->currentIndex() != index) pimpl->stack->setCurrentIndex(index); + + // 1 spacer item before the first action + QAction* toCheck = pimpl->toolbar->actions().at(index + 1); + if (pimpl->actionGroup->checkedAction() != toCheck) + toCheck->setChecked(true); } void QToolbarTabDialog::show() @@ -164,4 +170,4 @@ void QToolbarTabDialog::hide() pimpl->dialog.data()->hide(); } -#include "moc_qtoolbartabdialog_nonmac.cpp" +#include "qtoolbartabdialog.moc" diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index e0499e333..760660592 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -68,6 +68,8 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setAttribute( Qt::WA_MacShowFocusRect, 0 ); setContentsMargins( 0, 0, 0, 0 ); + tDebug() << "POINT SIZEL" << font().pointSize(); + QFont fnt; fnt.setPointSize( font().pointSize() - 1 ); setFont( fnt ); From a147494d00d4a3a47187b56ef2473c7c3c30953a Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 16:46:28 -0400 Subject: [PATCH 03/12] Tweak margins and sizehints --- src/SettingsDialog.cpp | 11 ++--------- src/Settings_Accounts.ui | 3 +++ src/Settings_Advanced.ui | 3 +++ src/Settings_Collection.ui | 3 +++ .../thirdparty/Qocoa/qtoolbartabdialog.cpp | 1 + 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index e04908a44..2730cf1b8 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -118,14 +118,6 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_advancedWidgetUi->aclEntryClearButton->setEnabled( TomahawkSettings::instance()->aclEntries().size() > 0 ); connect( m_advancedWidgetUi->aclEntryClearButton, SIGNAL( clicked( bool ) ), this, SLOT( aclEntryClearButtonClicked() ) ); -//#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 m_proxySettings.setSizeGripEnabled( true ); @@ -199,7 +191,6 @@ SettingsDialog::SettingsDialog(QObject *parent ) { m_collectionWidgetUi->dirTree->checkPath( dir, Qt::Checked ); } -// m_collectionWidgetUi->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() ); int buttonsWidth = qMax( m_advancedWidgetUi->proxyButton->sizeHint().width(), m_advancedWidgetUi->aclEntryClearButton->sizeHint().width() ); @@ -207,6 +198,8 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_advancedWidgetUi->aclEntryClearButton->setFixedWidth( buttonsWidth ); + m_advancedWidget->setMinimumSize( m_advancedWidget->sizeHint() ); + m_accountsWidget->setMinimumSize( 500, 400 ); // NOW PLAYING // #ifdef Q_WS_MAC // ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); diff --git a/src/Settings_Accounts.ui b/src/Settings_Accounts.ui index b7382c1c5..15c11cfdb 100644 --- a/src/Settings_Accounts.ui +++ b/src/Settings_Accounts.ui @@ -14,6 +14,9 @@ Form + + 0 + diff --git a/src/Settings_Advanced.ui b/src/Settings_Advanced.ui index c13f79b25..fe7482db9 100644 --- a/src/Settings_Advanced.ui +++ b/src/Settings_Advanced.ui @@ -14,6 +14,9 @@ Form + + 0 + diff --git a/src/Settings_Collection.ui b/src/Settings_Collection.ui index 3031f1dd8..0517b80e7 100644 --- a/src/Settings_Collection.ui +++ b/src/Settings_Collection.ui @@ -14,6 +14,9 @@ Form + + 0 + diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp index 89d0b10a6..4d7419915 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp +++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.cpp @@ -93,6 +93,7 @@ QToolbarTabDialog::QToolbarTabDialog() : pimpl->rightSpacer = pimpl->toolbar->addWidget(rightSpacer); pimpl->layout = new QVBoxLayout; + pimpl->layout->setContentsMargins( 4, 4, 4, 4 ); pimpl->layout->addWidget(pimpl->toolbar); pimpl->layout->addWidget(pimpl->separator); pimpl->layout->addWidget(pimpl->stack); From b8ccc250a9f2fae72c36467d00d76339eef89a6e Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 16:57:17 -0400 Subject: [PATCH 04/12] Remove point size debug --- src/sourcetree/SourceTreeView.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 760660592..e0499e333 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -68,8 +68,6 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setAttribute( Qt::WA_MacShowFocusRect, 0 ); setContentsMargins( 0, 0, 0, 0 ); - tDebug() << "POINT SIZEL" << font().pointSize(); - QFont fnt; fnt.setPointSize( font().pointSize() - 1 ); setFont( fnt ); From 8528ba7c72ae31ea70bc1b0050d14ff25964f8cf Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 17:08:12 -0400 Subject: [PATCH 05/12] Only set min width --- src/SettingsDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 2730cf1b8..4d0e9939c 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -199,7 +199,7 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_advancedWidget->setMinimumSize( m_advancedWidget->sizeHint() ); - m_accountsWidget->setMinimumSize( 500, 400 ); + m_accountsWidget->setMinimumWidth( 500 ); // NOW PLAYING // #ifdef Q_WS_MAC // ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); From 10fb76b92bd0bde054d371fec18c5d2b35ffa233 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 17:11:51 -0400 Subject: [PATCH 06/12] Set current index to 0 when showing --- src/SettingsDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 4d0e9939c..a31a4aac3 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -296,6 +296,7 @@ SettingsDialog::~SettingsDialog() void SettingsDialog::show() { + m_dialog->setCurrentIndex( 0 ); m_dialog->show(); } From 3f707790c45fe3e49999300a8da0b43a04f0f154 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 8 Aug 2012 17:27:35 -0400 Subject: [PATCH 07/12] No min sizes on mac --- src/SettingsDialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index a31a4aac3..b7ed66ba3 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -197,9 +197,11 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_advancedWidgetUi->proxyButton->setFixedWidth( buttonsWidth ); m_advancedWidgetUi->aclEntryClearButton->setFixedWidth( buttonsWidth ); - +#ifndef Q_OS_MAC m_advancedWidget->setMinimumSize( m_advancedWidget->sizeHint() ); m_accountsWidget->setMinimumWidth( 500 ); +#endif + // NOW PLAYING // #ifdef Q_WS_MAC // ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() ); From 6b36d143043257b4937c3b41b4754ff78d5d2f39 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Aug 2012 15:42:15 -0400 Subject: [PATCH 08/12] Update to Qocoa fixes --- src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h | 4 +-- .../thirdparty/Qocoa/qtoolbartabdialog.h | 22 +++++++++++++ .../thirdparty/Qocoa/qtoolbartabdialog_mac.mm | 33 +++++++++++++------ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h b/src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h index ee620a3a5..053f57a06 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h +++ b/src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h @@ -32,7 +32,7 @@ static inline NSString* fromQString(const QString &string) { const QByteArray utf8 = string.toUtf8(); const char* cString = utf8.constData(); - return [[NSString alloc] initWithUTF8String:cString]; + return [[[NSString alloc] initWithUTF8String:cString] autorelease]; } static inline QString toQString(NSString *string) @@ -45,7 +45,7 @@ static inline QString toQString(NSString *string) static inline NSImage* fromQPixmap(const QPixmap &pixmap) { CGImageRef cgImage = pixmap.toMacCGImageRef(); - return [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize]; + return [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease]; } static inline void setupLayout(void *cocoaView, QWidget *parent) diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h index 3949bd6f9..d1e9aee74 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h +++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog.h @@ -1,3 +1,25 @@ +/* + 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. + */ + #ifndef QTOOLBARTABWIDGET_H #define QTOOLBARTABWIDGET_H diff --git a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm index e36a1f15e..7c5fbced2 100644 --- a/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm +++ b/src/libtomahawk/thirdparty/Qocoa/qtoolbartabdialog_mac.mm @@ -21,7 +21,6 @@ */ #include "qtoolbartabdialog.h" -#include "moc_qtoolbartabdialog.cpp" #include "qocoa_mac.h" @@ -90,7 +89,7 @@ class QToolbarTabDialogPrivate { public: QToolbarTabDialogPrivate(QToolbarTabDialog* dialog) : q(dialog), currentPane(NULL), - minimumWidthForToolbar(0) + minimumWidth(0) { } @@ -116,7 +115,7 @@ public: [prefsWindow setFrame:windowFrame display:NO]; [prefsWindow setMinSize: windowFrame.size]; } - minimumWidthForToolbar = windowFrame.size.width; + minimumWidth = windowFrame.size.width; } void showPaneWithIdentifier(NSString* ident) { @@ -136,6 +135,8 @@ public: Q_ASSERT(newPage); if (!newPage) return; + + const NSRect oldFrame = [[prefsWindow contentView] frame]; // Clear first responder on window and set a temporary NSView on the window // while we change the widget out underneath @@ -146,6 +147,8 @@ public: [tempView release]; QSize sizeToUse = newPage->sizeHint().isNull() ? newPage->size() : newPage->sizeHint(); + sizeToUse.setWidth(qMax(sizeToUse.width(), newPage->minimumWidth())); + sizeToUse.setHeight(qMax(sizeToUse.height(), newPage->minimumHeight())); static const int spacing = 4; @@ -156,8 +159,10 @@ public: 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; + // Don't resize the width---only the height, so use the maximum width for any page + // or the same width as before, if the user already resized it to be larger. + newFrame.size.width < minimumWidth ? newFrame.size.width = minimumWidth + : newFrame.size.width = qMax(newFrame.size.width, oldFrame.size.width); // Preserve upper left point of window during resize. newFrame.origin.y += ([[prefsWindow contentView] frame].size.height - sizeToUse.height()) - spacing; @@ -180,11 +185,11 @@ public: if (newPage->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed) { canResize = NO; - maxSize.width = minSize.width; + maxSize.width = sizeToUse.width(); } if (newPage->sizePolicy().verticalPolicy() == QSizePolicy::Fixed) { canResize = NO; - maxSize.height = minSize.height; + maxSize.height = sizeToUse.height(); } @@ -192,6 +197,7 @@ public: [prefsWindow setShowsResizeIndicator:canResize]; [prefsWindow setTitle:ident]; + [prefsWindow makeFirstResponder:[panes objectForKey:ident]]; [pool drain]; } @@ -220,7 +226,7 @@ public: NSToolbar *toolBar; NSString* currentPane; - int minimumWidthForToolbar; + int minimumWidth; }; @@ -320,11 +326,10 @@ public: -(NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize { - Q_UNUSED(sender); if (!pimpl) return frameSize; - pimpl->resizeCurrentPageToSize(frameSize); + pimpl->resizeCurrentPageToSize([[sender contentView] frame].size); return frameSize; } @@ -398,6 +403,8 @@ void QToolbarTabDialog::addTab(QWidget* page, const QPixmap& icon, const QString [nativeView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [nativeView setAutoresizesSubviews:YES]; + pimpl->minimumWidth = qMax(pimpl->minimumWidth, page->sizeHint().width()); + nativeWidget->show(); ItemData data; @@ -433,6 +440,11 @@ void QToolbarTabDialog::setCurrentIndex(int index) void QToolbarTabDialog::show() { + Q_ASSERT(pimpl); + if (!pimpl) + return; + + [pimpl->prefsWindow center]; [pimpl->prefsWindow makeKeyAndOrderFront:nil]; } @@ -446,3 +458,4 @@ void QToolbarTabDialog::hide() emit accepted(); } +#include "moc_qtoolbartabdialog.cpp" From 9d677160675205fbe87f4dcf8872ae2bcf04b377 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Fri, 10 Aug 2012 15:42:35 -0400 Subject: [PATCH 09/12] OS X tweaks for settings dialog --- src/SettingsDialog.cpp | 4 ++++ src/Settings_Accounts.ui | 12 +++++++++--- src/Settings_Advanced.ui | 8 +++++++- src/Settings_Collection.ui | 8 +++++++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index b7ed66ba3..92239b99a 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -200,6 +200,10 @@ SettingsDialog::SettingsDialog(QObject *parent ) #ifndef Q_OS_MAC m_advancedWidget->setMinimumSize( m_advancedWidget->sizeHint() ); m_accountsWidget->setMinimumWidth( 500 ); +#else + m_accountsWidget->setMinimumSize( 500, 350 ); + m_collectionWidget->setMinimumHeight( m_collectionWidget->sizeHint().height() + 20 ); + m_advancedWidget->setMinimumHeight( m_advancedWidget->sizeHint().height() + 4 ); #endif // NOW PLAYING diff --git a/src/Settings_Accounts.ui b/src/Settings_Accounts.ui index 15c11cfdb..bea5d27b2 100644 --- a/src/Settings_Accounts.ui +++ b/src/Settings_Accounts.ui @@ -6,8 +6,8 @@ 0 0 - 508 - 476 + 405 + 347 @@ -15,7 +15,7 @@ - 0 + 2 @@ -56,6 +56,12 @@ true + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + diff --git a/src/Settings_Advanced.ui b/src/Settings_Advanced.ui index fe7482db9..324bace00 100644 --- a/src/Settings_Advanced.ui +++ b/src/Settings_Advanced.ui @@ -10,12 +10,18 @@ 475 + + + 0 + 0 + + Form - 0 + 2 diff --git a/src/Settings_Collection.ui b/src/Settings_Collection.ui index 0517b80e7..a8899f57c 100644 --- a/src/Settings_Collection.ui +++ b/src/Settings_Collection.ui @@ -10,12 +10,18 @@ 388 + + + 0 + 0 + + Form - 0 + 2 From ca787c58eb5eb209a1a8791f75d881e88b8a77b9 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 14 Aug 2012 23:23:34 -0400 Subject: [PATCH 10/12] More OS X preferences fixes --- src/SettingsDialog.cpp | 26 +- src/Settings_Accounts.ui | 21 +- src/Settings_Collection.ui | 4 +- src/libtomahawk/CMakeLists.txt | 3 +- src/libtomahawk/thirdparty/Qocoa/qbutton.cpp | 89 +++++++ src/libtomahawk/thirdparty/Qocoa/qbutton.h | 51 ++++ .../thirdparty/Qocoa/qbutton_mac.mm | 232 ++++++++++++++++++ 7 files changed, 407 insertions(+), 19 deletions(-) create mode 100644 src/libtomahawk/thirdparty/Qocoa/qbutton.cpp create mode 100644 src/libtomahawk/thirdparty/Qocoa/qbutton.h create mode 100644 src/libtomahawk/thirdparty/Qocoa/qbutton_mac.mm diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 92239b99a..999372fdc 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -54,6 +54,7 @@ #include "accounts/AccountFactoryWrapper.h" #include "accounts/spotify/SpotifyAccount.h" #include "thirdparty/Qocoa/qtoolbartabdialog.h" +#include "thirdparty/Qocoa/qbutton.h" #include "ui_ProxyDialog.h" #include "ui_Settings_Accounts.h" @@ -81,18 +82,12 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_collectionWidgetUi->setupUi( m_collectionWidget ); m_advancedWidgetUi->setupUi( m_advancedWidget ); + m_accountsWidgetUi->accountsFilterCombo->setFocusPolicy( Qt::NoFocus ); + m_dialog = new QToolbarTabDialog; TomahawkSettings* s = TomahawkSettings::instance(); -// 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 m_advancedWidgetUi->checkBoxReporter->setChecked( s->crashReporterEnabled() ); m_advancedWidgetUi->checkBoxHttp->setChecked( s->httpEnabled() ); @@ -125,6 +120,8 @@ SettingsDialog::SettingsDialog(QObject *parent ) p->setFixedSize( 0, 0 ); #endif + m_accountsWidgetUi->installFromFileBtn->setText( tr( "Install from file" ) ); + // Accounts AccountDelegate* accountDelegate = new AccountDelegate( this ); m_accountsWidgetUi->accountsView->setItemDelegate( accountDelegate ); @@ -201,9 +198,16 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_advancedWidget->setMinimumSize( m_advancedWidget->sizeHint() ); m_accountsWidget->setMinimumWidth( 500 ); #else - m_accountsWidget->setMinimumSize( 500, 350 ); - m_collectionWidget->setMinimumHeight( m_collectionWidget->sizeHint().height() + 20 ); - m_advancedWidget->setMinimumHeight( m_advancedWidget->sizeHint().height() + 4 ); + m_accountsWidget->setContentsMargins( 6, 6, 6, 6 ); + m_accountsWidgetUi->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); + m_accountsWidgetUi->installFromFileBtn->setContentsMargins( -4, 0, 0, 0 ); + m_accountsWidget->setMinimumSize( 550, 400 ); + + m_collectionWidget->setContentsMargins( 6, 6, 6, 6 ); + m_collectionWidget->setMinimumHeight( m_collectionWidgetUi->verticalLayout->sizeHint().height() + 20 ); + + m_advancedWidget->setContentsMargins( 6, 6, 6, 6 ); + m_advancedWidget->setMinimumHeight( m_advancedWidgetUi->verticalLayout->sizeHint().height() ); #endif // NOW PLAYING diff --git a/src/Settings_Accounts.ui b/src/Settings_Accounts.ui index bea5d27b2..d0a0bd4ec 100644 --- a/src/Settings_Accounts.ui +++ b/src/Settings_Accounts.ui @@ -6,8 +6,8 @@ 0 0 - 405 - 347 + 553 + 439 @@ -20,9 +20,12 @@ - - - Install from file... + + + + 0 + 0 + @@ -66,6 +69,14 @@ + + + QButton + QWidget +
thirdparty/Qocoa/QButton.h
+ 1 +
+
diff --git a/src/Settings_Collection.ui b/src/Settings_Collection.ui index a8899f57c..6579d2d51 100644 --- a/src/Settings_Collection.ui +++ b/src/Settings_Collection.ui @@ -6,8 +6,8 @@ 0 0 - 423 - 388 + 403 + 370 diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 7cb8b637a..ecec610b1 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -391,6 +391,7 @@ IF( APPLE ) SET( libSources ${libSources} utils/TomahawkUtils_Mac.mm mac/FileHelpers.mm + thirdparty/Qocoa/qbutton_mac.mm thirdparty/Qocoa/qsearchfield_mac.mm thirdparty/Qocoa/qtoolbartabdialog_mac.mm widgets/SourceTreePopupDialog_mac.mm ) @@ -409,7 +410,7 @@ IF( APPLE ) /System/Library/Frameworks/Security.framework ) ELSE( APPLE ) - SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp thirdparty/Qocoa/qtoolbartabdialog.cpp ) + SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qbutton.cpp thirdparty/Qocoa/qsearchfield.cpp thirdparty/Qocoa/qtoolbartabdialog.cpp ) ENDIF( APPLE ) IF(LIBLASTFM_FOUND) diff --git a/src/libtomahawk/thirdparty/Qocoa/qbutton.cpp b/src/libtomahawk/thirdparty/Qocoa/qbutton.cpp new file mode 100644 index 000000000..0a79e2baf --- /dev/null +++ b/src/libtomahawk/thirdparty/Qocoa/qbutton.cpp @@ -0,0 +1,89 @@ +/* +Copyright (C) 2011 by Mike McQuaid + +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 "qbutton.h" + +#include +#include +#include +#include + +class QButtonPrivate : public QObject +{ +public: + QButtonPrivate(QButton *button, QAbstractButton *abstractButton) + : QObject(button), abstractButton(abstractButton) {} + QPointer abstractButton; +}; + +QButton::QButton(QWidget *parent, BezelStyle) : QWidget(parent) +{ + QAbstractButton *button = 0; + if (qobject_cast(parent)) + button = new QToolButton(this); + else + button = new QPushButton(this); + connect(button, SIGNAL(clicked()), + this, SIGNAL(clicked())); + pimpl = new QButtonPrivate(this, button); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(button); +} + +void QButton::setText(const QString &text) +{ + Q_ASSERT(pimpl); + if (pimpl) + pimpl->abstractButton->setText(text); +} + +void QButton::setImage(const QPixmap &image) +{ + Q_ASSERT(pimpl); + if (pimpl) + pimpl->abstractButton->setIcon(image); +} + +void QButton::setChecked(bool checked) +{ + Q_ASSERT(pimpl); + if (pimpl) + pimpl->abstractButton->setChecked(checked); +} + +void QButton::setCheckable(bool checkable) +{ + Q_ASSERT(pimpl); + if (pimpl) + pimpl->abstractButton->setCheckable(checkable); +} + +bool QButton::isChecked() +{ + Q_ASSERT(pimpl); + if (!pimpl) + return false; + + return pimpl->abstractButton->isChecked(); +} diff --git a/src/libtomahawk/thirdparty/Qocoa/qbutton.h b/src/libtomahawk/thirdparty/Qocoa/qbutton.h new file mode 100644 index 000000000..591c37ffc --- /dev/null +++ b/src/libtomahawk/thirdparty/Qocoa/qbutton.h @@ -0,0 +1,51 @@ +#ifndef QBUTTON_H +#define QBUTTON_H + +#include +#include + +#include "DllMacro.h" + +class QButtonPrivate; +class DLLEXPORT QButton : public QWidget +{ + Q_OBJECT +public: + // Matches NSBezelStyle + enum BezelStyle { + Rounded = 1, + RegularSquare = 2, + Disclosure = 5, + ShadowlessSquare = 6, + Circular = 7, + TexturedSquare = 8, + HelpButton = 9, + SmallSquare = 10, + TexturedRounded = 11, + RoundRect = 12, + Recessed = 13, + RoundedDisclosure = 14, +#ifdef __MAC_10_7 + Inline = 15 +#endif + }; + + explicit QButton(QWidget *parent, BezelStyle bezelStyle = Rounded); + +public slots: + void setText(const QString &text); + void setImage(const QPixmap &image); + void setChecked(bool checked); + +public: + void setCheckable(bool checkable); + bool isChecked(); + +signals: + void clicked(bool checked = false); + +private: + friend class QButtonPrivate; + QPointer pimpl; +}; +#endif // QBUTTON_H diff --git a/src/libtomahawk/thirdparty/Qocoa/qbutton_mac.mm b/src/libtomahawk/thirdparty/Qocoa/qbutton_mac.mm new file mode 100644 index 000000000..9dfdf9672 --- /dev/null +++ b/src/libtomahawk/thirdparty/Qocoa/qbutton_mac.mm @@ -0,0 +1,232 @@ +/* +Copyright (C) 2011 by Mike McQuaid + +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 "qbutton.h" + +#include "qocoa_mac.h" + +#import "Foundation/NSAutoreleasePool.h" +#import "AppKit/NSButton.h" +#import "AppKit/NSFont.h" + +class QButtonPrivate : public QObject +{ +public: + QButtonPrivate(QButton *qButton, NSButton *nsButton, QButton::BezelStyle bezelStyle) + : QObject(qButton), qButton(qButton), nsButton(nsButton) + { + switch(bezelStyle) { + case QButton::Disclosure: + case QButton::Circular: +#ifdef __MAC_10_7 + case QButton::Inline: +#endif + case QButton::RoundedDisclosure: + case QButton::HelpButton: + [nsButton setTitle:@""]; + default: + break; + } + + NSFont* font = 0; + switch(bezelStyle) { + case QButton::RoundRect: + font = [NSFont fontWithName:@"Lucida Grande" size:12]; + break; + + case QButton::Recessed: + font = [NSFont fontWithName:@"Lucida Grande Bold" size:12]; + break; + +#ifdef __MAC_10_7 + case QButton::Inline: + font = [NSFont boldSystemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + break; +#endif + + default: + font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; + break; + } + [nsButton setFont:font]; + + switch(bezelStyle) { + case QButton::Rounded: + qButton->setMinimumWidth(40); + qButton->setFixedHeight(24); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + break; + case QButton::RegularSquare: + case QButton::TexturedSquare: + qButton->setMinimumSize(14, 23); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + break; + case QButton::ShadowlessSquare: + qButton->setMinimumSize(5, 25); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + break; + case QButton::SmallSquare: + qButton->setMinimumSize(4, 21); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + break; + case QButton::TexturedRounded: + qButton->setMinimumSize(10, 22); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + break; + case QButton::RoundRect: + case QButton::Recessed: + qButton->setMinimumWidth(16); + qButton->setFixedHeight(18); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + break; + case QButton::Disclosure: + qButton->setMinimumWidth(13); + qButton->setFixedHeight(13); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + break; + case QButton::Circular: + qButton->setMinimumSize(16, 16); + qButton->setMaximumHeight(40); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + break; + case QButton::HelpButton: + case QButton::RoundedDisclosure: + qButton->setMinimumWidth(22); + qButton->setFixedHeight(22); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + break; +#ifdef __MAC_10_7 + case QButton::Inline: + qButton->setMinimumWidth(10); + qButton->setFixedHeight(16); + qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + break; +#endif + } + + switch(bezelStyle) { + case QButton::Recessed: + [nsButton setButtonType:NSPushOnPushOffButton]; + case QButton::Disclosure: + [nsButton setButtonType:NSOnOffButton]; + default: + [nsButton setButtonType:NSMomentaryPushInButton]; + } + + [nsButton setBezelStyle:bezelStyle]; + } + + void clicked() + { + emit qButton->clicked(qButton->isChecked()); + } + + ~QButtonPrivate() { + [[nsButton target] release]; + [nsButton setTarget:nil]; + } + + QButton *qButton; + NSButton *nsButton; +}; + +@interface QButtonTarget : NSObject +{ +@public + QPointer pimpl; +} +-(void)clicked; +@end + +@implementation QButtonTarget +-(void)clicked { + Q_ASSERT(pimpl); + if (pimpl) + pimpl->clicked(); +} +@end + +QButton::QButton(QWidget *parent, BezelStyle bezelStyle) : QWidget(parent) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSButton *button = [[NSButton alloc] init]; + pimpl = new QButtonPrivate(this, button, bezelStyle); + + QButtonTarget *target = [[QButtonTarget alloc] init]; + target->pimpl = pimpl; + [button setTarget:target]; + + [button setAction:@selector(clicked)]; + + setupLayout(button, this); + + [button release]; + + [pool drain]; +} + +void QButton::setText(const QString &text) +{ + Q_ASSERT(pimpl); + if (!pimpl) + return; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [pimpl->nsButton setTitle:fromQString(text)]; + [pool drain]; +} + +void QButton::setImage(const QPixmap &image) +{ + Q_ASSERT(pimpl); + if (pimpl) + [pimpl->nsButton setImage:fromQPixmap(image)]; +} + +void QButton::setChecked(bool checked) +{ + Q_ASSERT(pimpl); + if (pimpl) + [pimpl->nsButton setState:checked]; +} + +void QButton::setCheckable(bool checkable) +{ + const NSInteger cellMask = checkable ? NSChangeBackgroundCellMask : NSNoCellMask; + + Q_ASSERT(pimpl); + if (pimpl) + [[pimpl->nsButton cell] setShowsStateBy:cellMask]; +} + +bool QButton::isChecked() +{ + Q_ASSERT(pimpl); + if (!pimpl) + return false; + + return [pimpl->nsButton state]; +} + +#include "moc_qbutton.cpp" + From 9964609c9482f759e185496d21744628a91547d2 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 15 Aug 2012 08:11:25 -0400 Subject: [PATCH 11/12] capitalization fix --- src/Settings_Accounts.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Settings_Accounts.ui b/src/Settings_Accounts.ui index d0a0bd4ec..de51ed1f0 100644 --- a/src/Settings_Accounts.ui +++ b/src/Settings_Accounts.ui @@ -73,7 +73,7 @@ QButton QWidget -
thirdparty/Qocoa/QButton.h
+
thirdparty/Qocoa/qbutton.h
1
From 0ae1088652bd4d15ebfd6280e7cb568861df68a8 Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 16 Aug 2012 21:53:49 -0400 Subject: [PATCH 12/12] Remove rich text from tab tooltips, and don't show focus frame on osx --- src/SettingsDialog.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 999372fdc..e573842c4 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -202,9 +202,11 @@ SettingsDialog::SettingsDialog(QObject *parent ) m_accountsWidgetUi->horizontalLayout->setContentsMargins( 0, 0, 0, 0 ); m_accountsWidgetUi->installFromFileBtn->setContentsMargins( -4, 0, 0, 0 ); m_accountsWidget->setMinimumSize( 550, 400 ); + m_accountsWidgetUi->accountsView->setAttribute( Qt::WA_MacShowFocusRect, false ); m_collectionWidget->setContentsMargins( 6, 6, 6, 6 ); m_collectionWidget->setMinimumHeight( m_collectionWidgetUi->verticalLayout->sizeHint().height() + 20 ); + m_collectionWidgetUi->dirTree->setAttribute( Qt::WA_MacShowFocusRect, false ); m_advancedWidget->setContentsMargins( 6, 6, 6, 6 ); m_advancedWidget->setMinimumHeight( m_advancedWidgetUi->verticalLayout->sizeHint().height() ); @@ -217,18 +219,15 @@ SettingsDialog::SettingsDialog(QObject *parent ) // ui->checkBoxEnableAdium->hide(); // #endif - 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_accountsWidget, QPixmap( RESPATH "images/account-settings.png" ), tr( "Services" ), tr( "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_collectionWidget, QPixmap( RESPATH "images/music-settings.png" ), tr( "Collection" ), tr( "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->addTab( m_advancedWidget, QPixmap( RESPATH "images/advanced-settings.png" ), tr( "Advanced" ), tr( "Configure Tomahawk's advanced settings, including " + "network connectivity settings, browser interaction " + "and more." ) ); m_dialog->setCurrentIndex( 0 );