diff --git a/src/properties/properties.pri b/src/properties/properties.pri index c714dc0e8..d90eb12cf 100644 --- a/src/properties/properties.pri +++ b/src/properties/properties.pri @@ -18,3 +18,9 @@ INCLUDEPATH += $$PWD $$PWD/trackerlist.cpp } + +HEADERS += \ + properties/proptabbar.h + +SOURCES += \ + properties/proptabbar.cpp diff --git a/src/properties/propertieswidget.cpp b/src/properties/propertieswidget.cpp index 1e859b94e..c07778a10 100644 --- a/src/properties/propertieswidget.cpp +++ b/src/properties/propertieswidget.cpp @@ -53,27 +53,13 @@ #include "downloadedpiecesbar.h" #include "pieceavailabilitybar.h" #include "qinisettings.h" - -#ifdef Q_WS_MAC -#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 8px; margin-right: 8px;}" -#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px;background-color: rgb(255, 208, 105); margin-left: 8px; margin-right: 8px;}" -#else -#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 3px; margin-right: 3px;}" -#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px;background-color: rgb(255, 208, 105); margin-left: 3px; margin-right: 3px;}" -#endif +#include "proptabbar.h" PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferListWidget *transferList, QBtSession* BTSession): QWidget(parent), transferList(transferList), main_window(main_window), BTSession(BTSession) { setupUi(this); state = VISIBLE; setEnabled(false); - // Buttons stylesheet - trackers_button->setStyleSheet(DEFAULT_BUTTON_CSS); - peers_button->setStyleSheet(DEFAULT_BUTTON_CSS); - url_seeds_button->setStyleSheet(DEFAULT_BUTTON_CSS); - files_button->setStyleSheet(DEFAULT_BUTTON_CSS); - main_infos_button->setStyleSheet(DEFAULT_BUTTON_CSS); - main_infos_button->setShortcut(QKeySequence(QString::fromUtf8("Alt+P"))); // Set Properties list model PropListModel = new TorrentFilesModel(); @@ -115,6 +101,11 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferLi // Peers list peersList = new PeerListWidget(this); peerpage_layout->addWidget(peersList); + // Tab bar + m_tabBar = new PropTabBar(); + verticalLayout->addLayout(m_tabBar); + connect(m_tabBar, SIGNAL(tabChanged(int)), stackedProperties, SLOT(setCurrentIndex(int))); + connect(m_tabBar, SIGNAL(visibilityToggled(bool)), SLOT(setVisibility(bool))); // Dynamic data refresher refreshTimer = new QTimer(this); connect(refreshTimer, SIGNAL(timeout()), this, SLOT(loadDynamicData())); @@ -129,6 +120,7 @@ PropertiesWidget::~PropertiesWidget() { delete pieces_availability; delete PropListModel; delete PropDelegate; + delete m_tabBar; } void PropertiesWidget::showPiecesAvailability(bool show) { @@ -147,8 +139,8 @@ void PropertiesWidget::showPiecesDownloaded(bool show) { line_2->setVisible(show); } -void PropertiesWidget::reduce() { - if(state == VISIBLE) { +void PropertiesWidget::setVisibility(bool visible) { + if(!visible && state == VISIBLE) { QSplitter *hSplitter = static_cast(parentWidget()); slideSizes = hSplitter->sizes(); stackedProperties->setVisible(false); @@ -159,10 +151,8 @@ void PropertiesWidget::reduce() { hSplitter->handle(1)->setDisabled(true); state = REDUCED; } -} -void PropertiesWidget::slide() { - if(state == REDUCED) { + if(visible && state == REDUCED) { stackedProperties->setVisible(true); QSplitter *hSplitter = static_cast(parentWidget()); hSplitter->handle(1)->setDisabled(false); @@ -285,12 +275,10 @@ void PropertiesWidget::readSettings() { hSplitter->setSizes(slideSizes); } if(!settings.value("TorrentProperties/Visible", false).toBool()) { - reduce(); + setVisibility(false); } - const int current_tab = settings.value("TorrentProperties/CurrentTab", MAIN_TAB).toInt(); - stackedProperties->setCurrentIndex(current_tab); - if(state != REDUCED) - getButtonFromIndex(current_tab)->setStyleSheet(SELECTED_BUTTON_CSS); + const int current_tab = settings.value("TorrentProperties/CurrentTab", PropTabBar::MAIN_TAB).toInt(); + m_tabBar->setCurrentIndex(current_tab); } void PropertiesWidget::saveSettings() { @@ -313,7 +301,7 @@ void PropertiesWidget::saveSettings() { settings.setValue(QString::fromUtf8("TorrentProperties/SplitterSizes"), QVariant(QString::number(sizes.first())+','+QString::number(sizes.last()))); } // Remember current tab - settings.setValue("TorrentProperties/CurrentTab", stackedProperties->currentIndex()); + settings.setValue("TorrentProperties/CurrentTab", m_tabBar->currentIndex()); } void PropertiesWidget::reloadPreferences() { @@ -327,7 +315,7 @@ void PropertiesWidget::loadDynamicData() { if(!h.is_valid() || main_window->getCurrentTabWidget() != transferList || state != VISIBLE) return; try { // Transfer infos - if(stackedProperties->currentIndex() == MAIN_TAB) { + if(stackedProperties->currentIndex() == PropTabBar::MAIN_TAB) { wasted->setText(misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes())); upTotal->setText(misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")"); dlTotal->setText(misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")"); @@ -380,17 +368,17 @@ void PropertiesWidget::loadDynamicData() { } return; } - if(stackedProperties->currentIndex() == TRACKERS_TAB) { + if(stackedProperties->currentIndex() == PropTabBar::TRACKERS_TAB) { // Trackers trackerList->loadTrackers(); return; } - if(stackedProperties->currentIndex() == PEERS_TAB) { + if(stackedProperties->currentIndex() == PropTabBar::PEERS_TAB) { // Load peers peersList->loadPeers(h); return; } - if(stackedProperties->currentIndex() == FILES_TAB) { + if(stackedProperties->currentIndex() == PropTabBar::FILES_TAB) { // Files progress if(h.is_valid() && h.has_metadata()) { if(PropListModel->rowCount() == 0) { @@ -441,82 +429,6 @@ void PropertiesWidget::loadUrlSeeds(){ } } -/* Tab buttons */ -QPushButton* PropertiesWidget::getButtonFromIndex(int index) { - switch(index) { - case TRACKERS_TAB: - return trackers_button; - case PEERS_TAB: - return peers_button; - case URLSEEDS_TAB: - return url_seeds_button; - case FILES_TAB: - return files_button; - default: - return main_infos_button; - } -} - -void PropertiesWidget::on_main_infos_button_clicked() { - if(state == VISIBLE && stackedProperties->currentIndex() == MAIN_TAB) { - reduce(); - main_infos_button->setStyleSheet(DEFAULT_BUTTON_CSS); - } else { - slide(); - getButtonFromIndex(stackedProperties->currentIndex())->setStyleSheet(DEFAULT_BUTTON_CSS); - stackedProperties->setCurrentIndex(MAIN_TAB); - main_infos_button->setStyleSheet(SELECTED_BUTTON_CSS); - } -} - -void PropertiesWidget::on_trackers_button_clicked() { - if(state == VISIBLE && stackedProperties->currentIndex() == TRACKERS_TAB) { - reduce(); - } else { - trackers_button->setStyleSheet(DEFAULT_BUTTON_CSS); - slide(); - getButtonFromIndex(stackedProperties->currentIndex())->setStyleSheet(DEFAULT_BUTTON_CSS); - stackedProperties->setCurrentIndex(TRACKERS_TAB); - trackers_button->setStyleSheet(SELECTED_BUTTON_CSS); - } -} - -void PropertiesWidget::on_peers_button_clicked() { - if(state == VISIBLE && stackedProperties->currentIndex() == PEERS_TAB) { - reduce(); - peers_button->setStyleSheet(DEFAULT_BUTTON_CSS); - } else { - slide(); - getButtonFromIndex(stackedProperties->currentIndex())->setStyleSheet(DEFAULT_BUTTON_CSS); - stackedProperties->setCurrentIndex(PEERS_TAB); - peers_button->setStyleSheet(SELECTED_BUTTON_CSS); - } -} - -void PropertiesWidget::on_url_seeds_button_clicked() { - if(state == VISIBLE && stackedProperties->currentIndex() == URLSEEDS_TAB) { - reduce(); - url_seeds_button->setStyleSheet(DEFAULT_BUTTON_CSS); - } else { - slide(); - getButtonFromIndex(stackedProperties->currentIndex())->setStyleSheet(DEFAULT_BUTTON_CSS); - stackedProperties->setCurrentIndex(URLSEEDS_TAB); - url_seeds_button->setStyleSheet(SELECTED_BUTTON_CSS); - } -} - -void PropertiesWidget::on_files_button_clicked() { - if(state == VISIBLE && stackedProperties->currentIndex() == FILES_TAB) { - reduce(); - files_button->setStyleSheet(DEFAULT_BUTTON_CSS); - } else { - slide(); - getButtonFromIndex(stackedProperties->currentIndex())->setStyleSheet(DEFAULT_BUTTON_CSS); - stackedProperties->setCurrentIndex(FILES_TAB); - files_button->setStyleSheet(SELECTED_BUTTON_CSS); - } -} - void PropertiesWidget::openDoubleClickedFile(QModelIndex index) { if(!index.isValid()) return; if(!h.is_valid() || !h.has_metadata()) return; diff --git a/src/properties/propertieswidget.h b/src/properties/propertieswidget.h index de13ad906..2d79ec190 100644 --- a/src/properties/propertieswidget.h +++ b/src/properties/propertieswidget.h @@ -48,27 +48,12 @@ class TrackerList; class GUI; class DownloadedPiecesBar; class PieceAvailabilityBar; - -enum Tab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB}; -enum SlideState {REDUCED, VISIBLE}; +class PropTabBar; class PropertiesWidget : public QWidget, private Ui::PropertiesWidget { Q_OBJECT - -private: - TransferListWidget *transferList; - GUI *main_window; - QTorrentHandle h; - QTimer *refreshTimer; - QBtSession* BTSession; - SlideState state; - TorrentFilesModel *PropListModel; - PropListDelegate *PropDelegate; - PeerListWidget *peersList; - TrackerList *trackerList; - QList slideSizes; - DownloadedPiecesBar *downloaded_pieces; - PieceAvailabilityBar *pieces_availability; +public: + enum SlideState {REDUCED, VISIBLE}; public: PropertiesWidget(QWidget *parent, GUI* main_window, TransferListWidget *transferList, QBtSession* BTSession); @@ -87,11 +72,6 @@ protected slots: void loadTorrentInfos(QTorrentHandle &h); void updateTorrentInfos(QTorrentHandle &h); void loadUrlSeeds(); - void on_main_infos_button_clicked(); - void on_trackers_button_clicked(); - void on_peers_button_clicked(); - void on_url_seeds_button_clicked(); - void on_files_button_clicked(); void askWebSeed(); void deleteSelectedUrlSeeds(); void displayFilesListMenu(const QPoint& pos); @@ -104,9 +84,8 @@ protected slots: void selectNoneFiles(); public slots: + void setVisibility(bool visible); void loadDynamicData(); - void reduce(); - void slide(); void clear(); void readSettings(); void saveSettings(); @@ -114,6 +93,21 @@ public slots: void openDoubleClickedFile(QModelIndex); void updateSavePath(QTorrentHandle& h); +private: + TransferListWidget *transferList; + GUI *main_window; + QTorrentHandle h; + QTimer *refreshTimer; + QBtSession* BTSession; + SlideState state; + TorrentFilesModel *PropListModel; + PropListDelegate *PropDelegate; + PeerListWidget *peersList; + TrackerList *trackerList; + QList slideSizes; + DownloadedPiecesBar *downloaded_pieces; + PieceAvailabilityBar *pieces_availability; + PropTabBar *m_tabBar; }; #endif // PROPERTIESWIDGET_H diff --git a/src/properties/propertieswidget.ui b/src/properties/propertieswidget.ui index ad39c4b19..440f6cf72 100644 --- a/src/properties/propertieswidget.ui +++ b/src/properties/propertieswidget.ui @@ -54,8 +54,8 @@ 0 0 - 522 - 351 + 534 + 314 @@ -514,8 +514,11 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> +</style></head><body style=" font-family:'Ubuntu'; font-size:8pt; font-weight:400; font-style:normal;"> +<table style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> +<tr> +<td style="border: none;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans';"></p></td></tr></table></body></html> true @@ -811,110 +814,6 @@ p, li { white-space: pre-wrap; } 2 - - - - General - - - - :/Icons/oxygen/help-about.png:/Icons/oxygen/help-about.png - - - - 16 - 16 - - - - - - - - Trackers - - - - :/Icons/oxygen/network-server.png:/Icons/oxygen/network-server.png - - - - 16 - 16 - - - - - - - - - 0 - 24 - - - - Peers - - - - :/Icons/oxygen/peer.png:/Icons/oxygen/peer.png - - - - 16 - 16 - - - - - - - - URL seeds - - - - :/Icons/oxygen/urlseed.png:/Icons/oxygen/urlseed.png - - - - 16 - 16 - - - - - - - - Files - - - - :/Icons/oxygen/folder.png:/Icons/oxygen/folder.png - - - - 16 - 16 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/src/properties/proptabbar.cpp b/src/properties/proptabbar.cpp new file mode 100644 index 000000000..bd4b71015 --- /dev/null +++ b/src/properties/proptabbar.cpp @@ -0,0 +1,122 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#include "proptabbar.h" + +#ifdef Q_WS_MAC +#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 8px; margin-right: 8px;}" +#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px;background-color: rgb(255, 208, 105); margin-left: 8px; margin-right: 8px;}" +#else +#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px; margin-left: 3px; margin-right: 3px;}" +#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid rgb(85, 81, 91);border-radius: 3px;padding: 2px;background-color: rgb(255, 208, 105); margin-left: 3px; margin-right: 3px;}" +#endif + +const int BTN_ICON_SIZE = 16; + +PropTabBar::PropTabBar(QWidget *parent) : + QHBoxLayout(parent), m_currentIndex(-1) +{ + m_btnGroup = new QButtonGroup(this); + setContentsMargins(5, 4, 5, 2); + // General tab + QPushButton *main_infos_button = new QPushButton(QIcon(":/Icons/oxygen/help-about.png"), tr("General"), parent); + main_infos_button->setShortcut(QKeySequence(QString::fromUtf8("Alt+P"))); + main_infos_button->setStyleSheet(DEFAULT_BUTTON_CSS); + main_infos_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(main_infos_button); + m_btnGroup->addButton(main_infos_button, MAIN_TAB); + // Trackers tab + QPushButton *trackers_button = new QPushButton(QIcon(":/Icons/oxygen/network-server.png"), tr("Trackers"), parent); + trackers_button->setStyleSheet(DEFAULT_BUTTON_CSS); + trackers_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(trackers_button); + m_btnGroup->addButton(trackers_button, TRACKERS_TAB); + // Peers tab + QPushButton *peers_button = new QPushButton(QIcon(":/Icons/oxygen/peer.png"), tr("Peers"), parent); + peers_button->setStyleSheet(DEFAULT_BUTTON_CSS); + peers_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(peers_button); + m_btnGroup->addButton(peers_button, PEERS_TAB); + // URL seeds tab + QPushButton *urlseeds_button = new QPushButton(QIcon(":/Icons/oxygen/urlseed.png"), tr("URL Seeds"), parent); + urlseeds_button->setStyleSheet(DEFAULT_BUTTON_CSS); + urlseeds_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(urlseeds_button); + m_btnGroup->addButton(urlseeds_button, URLSEEDS_TAB); + // Files tab + QPushButton *files_button = new QPushButton(QIcon(":/Icons/oxygen/folder.png"), tr("Files"), parent); + files_button->setStyleSheet(DEFAULT_BUTTON_CSS); + files_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(files_button); + m_btnGroup->addButton(files_button, FILES_TAB); + // Spacer + addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + // SIGNAL/SLOT + connect(m_btnGroup, SIGNAL(buttonClicked(int)), SLOT(setCurrentIndex(int))); +} + +PropTabBar::~PropTabBar() { + delete m_btnGroup; +} + +int PropTabBar::currentIndex() const +{ + return m_currentIndex; +} + +void PropTabBar::setCurrentIndex(int index) +{ + // If asked to hide or if the currently selected tab is clicked + if(index < 0 || m_currentIndex == index) { + if(m_currentIndex >= 0) { + m_btnGroup->button(m_currentIndex)->setStyleSheet(DEFAULT_BUTTON_CSS); + m_currentIndex = -1; + emit visibilityToggled(false); + } + return; + } + // Unselect previous tab + if(m_currentIndex >= 0) { + m_btnGroup->button(m_currentIndex)->setStyleSheet(DEFAULT_BUTTON_CSS); + } else { + // Nothing was selected, show! + emit visibilityToggled(true); + } + // Select the new button + m_btnGroup->button(index)->setStyleSheet(SELECTED_BUTTON_CSS); + m_currentIndex = index; + // Emit the signal + emit tabChanged(index); +} diff --git a/src/properties/proptabbar.h b/src/properties/proptabbar.h new file mode 100644 index 000000000..20d0248dd --- /dev/null +++ b/src/properties/proptabbar.h @@ -0,0 +1,63 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PROPTABBAR_H +#define PROPTABBAR_H + +#include + +class QButtonGroup; + +class PropTabBar : public QHBoxLayout +{ + Q_OBJECT + +public: + enum PropertyTab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB}; + +public: + explicit PropTabBar(QWidget *parent = 0); + ~PropTabBar(); + int currentIndex() const; + +signals: + void tabChanged(int index); + void visibilityToggled(bool visible); + +public slots: + void setCurrentIndex(int index); + +private: + QButtonGroup *m_btnGroup; + int m_currentIndex; + +}; + +#endif // PROPTABBAR_H