PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *main_window, TransferListWidget *transferList)
    : QWidget(parent), transferList(transferList), main_window(main_window), m_torrent(0)
{
    setupUi(this);
    setAutoFillBackground(true);

    state = VISIBLE;

    // Set Properties list model
    PropListModel = new TorrentContentFilterModel();
    filesList->setModel(PropListModel);
    PropDelegate = new PropListDelegate(this);
    filesList->setItemDelegate(PropDelegate);
    filesList->setSortingEnabled(true);
    // Torrent content filtering
    m_contentFilterLine = new LineEdit(this);
    m_contentFilterLine->setPlaceholderText(tr("Filter files..."));
    m_contentFilterLine->setMaximumSize(300, m_contentFilterLine->size().height());
    connect(m_contentFilterLine, SIGNAL(textChanged(QString)), this, SLOT(filterText(QString)));
    contentFilterLayout->insertWidget(3, m_contentFilterLine);

    // SIGNAL/SLOTS
    connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&)));
    connect(selectAllButton, SIGNAL(clicked()), PropListModel, SLOT(selectAll()));
    connect(selectNoneButton, SIGNAL(clicked()), PropListModel, SLOT(selectNone()));
    connect(filesList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFilesListMenu(const QPoint&)));
    connect(filesList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(openDoubleClickedFile(const QModelIndex&)));
    connect(PropListModel, SIGNAL(filteredFilesChanged()), this, SLOT(filteredFilesChanged()));
    connect(listWebSeeds, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayWebSeedListMenu(const QPoint&)));
    connect(transferList, SIGNAL(currentTorrentChanged(BitTorrent::TorrentHandle * const)), this, SLOT(loadTorrentInfos(BitTorrent::TorrentHandle * const)));
    connect(PropDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(filteredFilesChanged()));
    connect(stackedProperties, SIGNAL(currentChanged(int)), this, SLOT(loadDynamicData()));
    connect(BitTorrent::Session::instance(), SIGNAL(torrentSavePathChanged(BitTorrent::TorrentHandle * const)), this, SLOT(updateSavePath(BitTorrent::TorrentHandle * const)));
    connect(BitTorrent::Session::instance(), SIGNAL(torrentMetadataLoaded(BitTorrent::TorrentHandle * const)), this, SLOT(updateTorrentInfos(BitTorrent::TorrentHandle * const)));
    connect(filesList->header(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveSettings()));
    connect(filesList->header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(saveSettings()));
    connect(filesList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSettings()));

#ifdef QBT_USES_QT5
    // set bar height relative to screen dpi
    int barHeight = devicePixelRatio() * 18;
#else
    // set bar height relative to font height
    QFont defFont;
    QFontMetrics fMetrics(defFont, 0); // need to be device-dependent
    int barHeight = fMetrics.height() * 5 / 4;
#endif

    // Downloaded pieces progress bar
    tempProgressBarArea->setVisible(false);
    downloaded_pieces = new DownloadedPiecesBar(this);
    groupBarLayout->addWidget(downloaded_pieces, 0, 1);
    downloaded_pieces->setFixedHeight(barHeight);
    downloaded_pieces->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // Pieces availability bar
    tempAvailabilityBarArea->setVisible(false);
    pieces_availability = new PieceAvailabilityBar(this);
    groupBarLayout->addWidget(pieces_availability, 1, 1);
    pieces_availability->setFixedHeight(barHeight);
    pieces_availability->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // Tracker list
    trackerList = new TrackerList(this);
    trackerUpButton->setIcon(GuiIconProvider::instance()->getIcon("go-up"));
    trackerUpButton->setIconSize(Utils::Misc::smallIconSize());
    trackerDownButton->setIcon(GuiIconProvider::instance()->getIcon("go-down"));
    trackerDownButton->setIconSize(Utils::Misc::smallIconSize());
    connect(trackerUpButton, SIGNAL(clicked()), trackerList, SLOT(moveSelectionUp()));
    connect(trackerDownButton, SIGNAL(clicked()), trackerList, SLOT(moveSelectionDown()));
    horizontalLayout_trackers->insertWidget(0, trackerList);
    connect(trackerList->header(), SIGNAL(sectionMoved(int,int,int)), trackerList, SLOT(saveSettings()));
    connect(trackerList->header(), SIGNAL(sectionResized(int,int,int)), trackerList, SLOT(saveSettings()));
    connect(trackerList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), trackerList, SLOT(saveSettings()));
    // Peers list
    peersList = new PeerListWidget(this);
    peerpage_layout->addWidget(peersList);
    connect(peersList->header(), SIGNAL(sectionMoved(int,int,int)), peersList, SLOT(saveSettings()));
    connect(peersList->header(), SIGNAL(sectionResized(int,int,int)), peersList, SLOT(saveSettings()));
    connect(peersList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), peersList, SLOT(saveSettings()));
    // Speed widget
    speedWidget = new SpeedWidget(this);
    speed_layout->addWidget(speedWidget);
    // Tab bar
    m_tabBar = new PropTabBar();
    m_tabBar->setContentsMargins(0, 5, 0, 0);
    verticalLayout->addLayout(m_tabBar);
    connect(m_tabBar, SIGNAL(tabChanged(int)), stackedProperties, SLOT(setCurrentIndex(int)));
    connect(m_tabBar, SIGNAL(tabChanged(int)), this, SLOT(saveSettings()));
    connect(m_tabBar, SIGNAL(visibilityToggled(bool)), SLOT(setVisibility(bool)));
    connect(m_tabBar, SIGNAL(visibilityToggled(bool)), this, SLOT(saveSettings()));
    // Dynamic data refresher
    refreshTimer = new QTimer(this);
    connect(refreshTimer, SIGNAL(timeout()), this, SLOT(loadDynamicData()));
    refreshTimer->start(3000); // 3sec
    editHotkeyFile = new QShortcut(Qt::Key_F2, filesList, 0, 0, Qt::WidgetShortcut);
    connect(editHotkeyFile, SIGNAL(activated()), SLOT(renameSelectedFile()));
    editHotkeyWeb = new QShortcut(Qt::Key_F2, listWebSeeds, 0, 0, Qt::WidgetShortcut);
    connect(editHotkeyWeb, SIGNAL(activated()), SLOT(editWebSeed()));
    connect(listWebSeeds, SIGNAL(doubleClicked(QModelIndex)), SLOT(editWebSeed()));
    deleteHotkeyWeb = new QShortcut(QKeySequence::Delete, listWebSeeds, 0, 0, Qt::WidgetShortcut);
    connect(deleteHotkeyWeb, SIGNAL(activated()), SLOT(deleteSelectedUrlSeeds()));
    openHotkeyFile = new QShortcut(Qt::Key_Return, filesList, 0, 0, Qt::WidgetShortcut);
    connect(openHotkeyFile, SIGNAL(activated()), SLOT(openSelectedFile()));
}