#include "burndata.h"
#include "ui_burndata.h"
#include "src/po/translation.h"
#include "src/frame/logger.h"
#include "src/frame/signals.h"
#include "src/frame/configuration.h"
#include "src/model/menufactory.h"
#include "src/model/logicmain.h"
#include "src/view/execdialog.h"
#include "src/view/filefilterrules.h"
#include "src/view/viewfilterfiles.h"
#include "src/view/mymenu.h"
#include "src/frame/signals.h"

#include <QDebug>
#include <QMessageBox>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QUrl>
#include <QFileInfo>
#include <QToolButton>
#include <QFileSystemWatcher>

BurnData *BurnData::m_oInstance = nullptr;
QMutex    BurnData::m_oMutex;

#define ICON_SIZE QSize(16, 16)

BurnData::BurnData(QWidget *parent) :
    QWidget(parent),
    m_oModel(new LogicBurnData(this)),
    m_oOpenFile(new ProcessOpenFile(QString(), this)),
    m_oPosition(0 , 0),
    ui(new Ui::BurnData)
{
    QFont  f;
    QToolButton *btn;
    ui->setupUi(this);

    m_oLinks.clear();
    btn = new QToolButton(this);
    btn->setAutoRaise(true);
    btn->setText("/");
    btn->setToolTip(_("root"));
    connect(btn, SIGNAL(clicked(bool)), this, SLOT(slotsLink()));
    m_oIndexes.clear();
    m_oLinks << btn;
    ui->link->insertWidget(0, m_oLinks.at(0));
    m_oLinks.at(0)->hide();

    f = ui->btnAdd->font();
    f.setPixelSize(14);
    ui->btnAdd->setFont(f);
    ui->btnAdd->setIcon(QIcon::fromTheme("list-add-symbolic"));
    ui->btnAdd->setText(_("Add(&A)"));
    ui->btnAdd->setProperty("useIconHighlightEffect", 0x8);
    ui->btnAdd->setIconSize(ICON_SIZE);
    ui->btnAdd->setCheckable(true);
    connect(ui->btnAdd, SIGNAL(toggled(bool)), this, SLOT(slotsAddFiles(bool)));
    connect(g_user_signal, &GlobalUserSignal::secondChangeDiscStatus, this, [&](){
        qDebug() << QString("【%1】【%2】我变了").arg(__func__).arg(__LINE__);
        ui->btnAdd->setEnabled(true);
    });

    ui->btnDelete->setFont(f);
    ui->btnDelete->setIcon(QIcon::fromTheme("edit-clear-symbolic"));
    ui->btnDelete->setText(_("Delete(&D)"));
    ui->btnDelete->setProperty("useIconHighlightEffect", 0x8);
    ui->btnDelete->setIconSize(ICON_SIZE);
    ui->btnDelete->setCheckable(true);
    connect(ui->btnDelete, SIGNAL(toggled(bool)), this, SLOT(slotsDeleteFiles(bool)));

    ui->btnClean->setFont(f);
    ui->btnClean->setIcon(QIcon::fromTheme("edit-delete-symbolic"));
    ui->btnClean->setText(_("Clean(&C)"));
    ui->btnClean->setProperty("useIconHighlightEffect", 0x8);
    ui->btnClean->setIconSize(ICON_SIZE);
    ui->btnClean->setCheckable(true);
    connect(ui->btnClean, SIGNAL(toggled(bool)), this, SLOT(slotsCleanFiles(bool)));

    ui->btnNewFolder->setFont(f);
    ui->btnNewFolder->setIcon(QIcon::fromTheme("folder-new-symbolic"));
    ui->btnNewFolder->setText(_("NewFolder(&N)"));
    ui->btnNewFolder->setProperty("useIconHighlightEffect", 0x8);
    ui->btnNewFolder->setIconSize(ICON_SIZE);
    ui->btnNewFolder->setCheckable(true);
    connect(ui->btnNewFolder, SIGNAL(toggled(bool)), this, SLOT(slotsNewFolder(bool)));

    ui->linkViewFilterFile->hide();
    ui->linkViewFilterFile->setFont(f);
    //connect(ui->linkViewFilterFile, SIGNAL(linkActivated(QString)), VIEWFILTERFILE, SLOT(show()));
    f = ui->labelWelcome->font();
    f.setPixelSize(14);
    ui->labelWelcome->setFont(f);
    ui->tip->setFont(f);
    ui->labelWelcome->setText(_("Welcome to use KylinBurner."));

    ui->labelProjectName->setFont(f);
    ui->labelProjectName->setText(_("ProjectSize:"));
    ui->labelProjectSize->setFont(f);
    ui->labelProjectSize->setText(_("0.00 MB"));
    ui->labelProjectName->hide();               //隐藏项目大小
    ui->labelProjectSize->hide();

    ui->treeView->setModel(m_oModel);
    ui->treeView->setFont(f);
    ui->treeView->header()->setFixedHeight(28);
    ui->treeView->header()->setAutoFillBackground(true);
    ui->tip->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->treeView->setAttribute(Qt::WA_TranslucentBackground, true);
    ui->treeView->setProperty("useIconHighlightEffect", 0x8);
    m_oModel->setHeaderData(0, Qt::Horizontal, _("FileName"), Qt::DisplayRole);
    m_oModel->setHeaderData(1, Qt::Horizontal, _("FileType"), Qt::DisplayRole);
    m_oModel->setHeaderData(2, Qt::Horizontal, _("FileSize"), Qt::DisplayRole);
    m_oModel->setHeaderData(3, Qt::Horizontal, _("FilePath"), Qt::DisplayRole);
    m_oModel->setHeaderData(4, Qt::Horizontal, _("FileTime"), Qt::DisplayRole);
    ui->treeView->sortByColumn(4);
    ui->treeView->header()->setSectionHidden(4, true);
    ui->treeView->header()->setStyleSheet("QHeaderView::section{border: 0px solid white;}");
    ui->treeView->setSelectionMode(QTreeView::ExtendedSelection);
    ui->treeView->setItemsExpandable(false);
    ui->treeView->setRootIsDecorated(false);
    ui->treeView->setSortingEnabled(false);
    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &BurnData::slotsTreeMenuByRightKey);

    ui->tip->installEventFilter(this);

    connect(m_oModel, &LogicBurnData::rootIndex, [=](QModelIndex idx){
        qDebug()<<__func__<<__LINE__<<"BurnData"<<idx;
        if (!idx.isValid())
        {
            refresh();
            return;
        }

        ui->treeView->setRootIndex(idx);
        m_oAddIndex = idx;
        if (m_oIndexes.size())
        {
            if (0 == m_oModel->level(idx))
            {
                m_oIndexes.replace(0, idx);
            }
        }
        else m_oIndexes << idx;
        refresh();
    });
    connect(m_oModel, SIGNAL(rootIndex(QModelIndex)), this, SLOT(slotsEntry(QModelIndex)));
    // connect(m_oModel, &LogicBurnData::rootIndex, [=](QModelIndex idx){linkEntry(idx);});
    connect(m_oModel, SIGNAL(updateDisk(int,void*)), this, SIGNAL(updateDisk(int,void*)));
    connect(this, SIGNAL(delData(int)), m_oModel, SLOT(deleteRoot(int)));
    connect(this, SIGNAL(changeCurrentIndex(int)), m_oModel, SLOT(changeIndex(int)));
    connect(ui->treeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotsEntry(QModelIndex)));
    connect(m_oModel, SIGNAL(size(ulong)), this, SLOT(slotsSize(ulong)));
    connect(m_oModel, SIGNAL(tip(bool)), this, SLOT(slotsTip(bool)));
    connect(m_oModel, SIGNAL(add(bool)), ui->btnAdd, SLOT(setEnabled(bool)));
    connect(m_oModel, SIGNAL(del(bool)), ui->btnDelete, SLOT(setEnabled(bool)));
    connect(m_oModel, SIGNAL(cls(bool)), ui->btnClean, SLOT(setEnabled(bool)));
    connect(m_oModel, SIGNAL(folder(bool)), ui->btnNewFolder, SLOT(setEnabled(bool)));
    connect(m_oModel, SIGNAL(doHidden(int,void*)), VIEWFILTERFILE, SLOT(filterHidden(int,void*)));
    connect(m_oModel, SIGNAL(doBroken(int,void*)), VIEWFILTERFILE, SLOT(filterBroken(int,void*)));
    connect(m_oModel, SIGNAL(doRepleace(int,void*)), VIEWFILTERFILE, SLOT(repleace(int,void*)));
    connect(ui->treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(slotsSelectionChanged()));
    connect(MAIN, SIGNAL(burnDataSetting()), m_oModel, SLOT(slotsSetting()));
    connect(MAIN, SIGNAL(createISO(void*)), m_oModel, SLOT(slotsCreateISO(void*)));
    connect(MAIN, SIGNAL(emptyMedium(void*)), m_oModel, SLOT(slotsCreateISO(void*)));
    connect(MAIN, SIGNAL(appendableMedium(void*)), m_oModel, SLOT(slotsCreateISO(void*)));
    connect(MAIN, SIGNAL(finishedMedium(void*)), m_oModel, SLOT(slotsCreateISO(void*)));
    connect(MAIN, SIGNAL(createISO(void*)), this, SIGNAL(newNode(void*)));
    connect(MAIN, SIGNAL(emptyMedium(void*)), this, SIGNAL(newNode(void*)));
    connect(MAIN, SIGNAL(appendableMedium(void*)), this, SIGNAL(newNode(void*)));
    connect(MAIN, SIGNAL(finishedMedium(void*)), this, SIGNAL(newNode(void*)));
    connect(this, SIGNAL(newNode(void*)), VIEWFILTERFILE, SLOT(newFilterRoot(void*)));
    connect(MAIN, SIGNAL(createISO()), m_oModel, SLOT(slotsCreateISO()));
    connect(MAIN, SIGNAL(burnData()), m_oModel, SLOT(slotsBurnData()));
    connect(MAIN, SIGNAL(addBurn()), m_oModel, SLOT(slotsBurnData()));

    //---------------add ---------------------------------
    connect(MAIN, SIGNAL(burnUDFData()), m_oModel , SLOT(slotsBurnUDFData()));
//    connect(MAIN, SIGNAL(appendableMedium(void*)), m_oModel, SLOT(slotsCreateISO(void *)));
    connect(MENU, &MenuFactory::fileFilter, [=](){
        qDebug()<<"BurnData"<<__func__<<__LINE__;
        if (CFG->get("FilterFile", "range", true).toBool()){
            m_oModel->filter();
        }else{
            m_oModel->filter(ui->treeView->rootIndex());
        }
        if (!FILTERRULES->isHidden())
            FILTERRULES->close();
        FILTERRULES->show();
    });
    connect(this, SIGNAL(viewFileterFile(bool)), MENU, SIGNAL(setViewFilterFile(bool)));
    connect(MENU, SIGNAL(viewFilterFile(bool)), VIEWFILTERFILE, SLOT(show()));
    connect(FILTERRULES, SIGNAL(rangeAll(bool)), this, SLOT(slotsRangeChange(bool)));
    connect(FILTERRULES, SIGNAL(hidden(bool)), this, SLOT(slotsFilterHidden(bool)));
    connect(FILTERRULES, SIGNAL(broken(bool)), this, SLOT(slotsFilterBroken(bool)));
    connect(FILTERRULES, SIGNAL(repleace(bool)), this, SLOT(slotsRepleaceSymbolLinks(bool)));
    connect(VIEWFILTERFILE, SIGNAL(recovery(QList<void*>,QList<void*>,QList<void*>)),
            m_oModel, SLOT(recovery(QList<void*>,QList<void*>,QList<void*>)));
    ui->lineEdit->hide();

    initAction();

    connect(g_user_signal, &GlobalUserSignal::iconChange, [=](QIcon icon){
        setWindowIcon(icon);
    });

    connect(g_user_signal, &GlobalUserSignal::sigMenuByRightMousePress, this, &BurnData::slotsTreeMenuByShortcutKey);

    refresh();
}

BurnData *BurnData::instance()
{
    if (nullptr == m_oInstance)
    {
        QMutexLocker locker(&m_oMutex);
        if (nullptr == m_oInstance)
        {
            m_oInstance = new BurnData();
        }
    }
    return m_oInstance;
}

void BurnData::refresh()
{
    int selecteds;
    // can add files
    if (!m_oModel->checkAdd(m_oAddIndex))
        m_oAddIndex = ui->treeView->rootIndex();
    m_oNewFolder->setEnabled(m_oModel->checkAdd(m_oAddIndex));
    m_oParent->setEnabled(ui->treeView->rootIndex().parent().isValid());
    m_oDelete->setEnabled(m_oModel->checkDel(ui->treeView->selectionModel()->selectedRows()));
    m_oRename->setEnabled(m_oModel->checkDel(ui->treeView->selectionModel()->selectedRows()));
    if (ui->treeView->selectionModel()->selectedRows().size() != 1) m_oRename->setEnabled(false);
    m_oOpen->setEnabled(m_oModel->checkOpen(ui->treeView->selectionModel()->selectedRows()));
    m_oOpenLocal->setEnabled(m_oModel->checkOpenLocal(ui->treeView->selectionModel()->selectedRows()));
    m_oProperties->setEnabled(m_oModel->checkProperties(ui->treeView->selectionModel()->selectedRows()));
    m_oModel->checkCls(ui->treeView->rootIndex());
    //ui->linkViewFilterFile->setHidden(!(VIEWFILTERFILE->filtered()));
    viewFileterFile(VIEWFILTERFILE->filtered());
    if (!(m_oModel->checkTip(ui->treeView->rootIndex())))
    {
        selecteds = ui->treeView->selectionModel()->selectedRows().count();
        if (selecteds > 1)
            ui->tip->setText(_("Selected %1 files of total %2 files")
                             .arg(selecteds).arg(m_oModel->rowCount(ui->treeView->rootIndex())));
        else
            ui->tip->setText(_("Selected %1 file of total %2 file(s)")
                             .arg(selecteds).arg(m_oModel->rowCount(ui->treeView->rootIndex())));
    }
    busness(m_oModel->checkSize());
}

void BurnData::addFiles(QStringList files)
{
    m_oModel->addDatasToIndex(m_oDialog.selectedFiles(), m_oAddIndex);
}

void BurnData::updatePosition(QPoint p)
{
    m_oPosition.setX(p.x());
    m_oPosition.setY(p.y());
}

bool BurnData::eventFilter(QObject *watched, QEvent *event)
{
    QDragEnterEvent *dragEvent;
    QDropEvent *dropEvent;
    QList<QUrl> urls;
    QString url;
    QStringList list;
    QFileInfo f;

    if (ui->tip == watched)
    {
        switch (event->type())
        {
        case QEvent::DragEnter:
            dragEvent = static_cast<QDragEnterEvent *>(event);
            urls = dragEvent->mimeData()->urls();
            while (urls.size())
            {
                //url = urls.takeFirst().toString(QUrl::RemoveScheme);
                url = QUrl::fromPercentEncoding(urls.takeFirst().toString(QUrl::RemoveScheme).toUtf8());
                f.setFile(url);
                if (!f.exists()) event->ignore();
                break;
            }
            if (!f.exists()) break;
            if (m_oModel->checkAdd(m_oAddIndex)) event->accept();
            else event->ignore();
            break;
        case QEvent::DragLeave:
            event->ignore();
            break;
        case QEvent::Drop:
            dropEvent = static_cast<QDropEvent *>(event);
            urls = dropEvent->mimeData()->urls();
            while (urls.size())
                //url = QUrl::fromPercentEncoding(urls.takeFirst().toString(QUrl::RemoveScheme).toUtf8());
                list << QUrl::fromPercentEncoding(urls.takeFirst().toString(QUrl::RemoveScheme).toUtf8());
            m_oModel->addDatasToIndex(list, m_oAddIndex);
            refresh();
            break;
        }
    }
    return QWidget::eventFilter(watched, event);
}

void BurnData::paintEvent(QPaintEvent *event)
{
    QPalette pal;

    pal = palette();


//    ui->linkViewFilterFile->setText(QString("<a href=# style=\"color: %1\">")
//                                    .arg(pal.windowText().color().name(QColor::HexRgb))
//                                    + _("ViewFilterFile(s)") + "</a>");

    QWidget::paintEvent(event);
}

void BurnData::resizeEvent(QResizeEvent *event)
{
    qreal basic;

    ui->treeView->header()->setFixedWidth(ui->treeView->width());

    basic = ui->treeView->header()->width() / 10;
    ui->treeView->header()->setSectionResizeMode(QHeaderView::Fixed);
    ui->treeView->header()->resizeSection(0, basic * 4);
    ui->treeView->header()->resizeSection(1, basic * 1.5);
    ui->treeView->header()->resizeSection(2, basic * 1.5);
    ui->treeView->header()->resizeSection(3, basic * 3);
    QWidget::resizeEvent(event);
}

void BurnData::keyPressEvent(QKeyEvent *event)
{
    // Shift+F10 展现上下文菜单
    if ((event->modifiers() == Qt::ShiftModifier) && (event->key() == Qt::Key_F10))
    {
//        qDebug() << " BurnData::keyPressEvent Shift+F10";
        slotsTreeMenuByShortcutKey();
        event->accept();
        return;
    }
    QWidget::keyPressEvent(event);
}

void BurnData::initAction()
{
    m_oMenu = new MyMenu(ui->treeView);
    m_oParent = new QAction(QIcon::fromTheme("go-up-symbolic"), _("Parent"), ui->treeView);
    m_oOpen = new QAction(QIcon::fromTheme("folder-open"), _("Open"), ui->treeView);
    m_oOpenLocal = new QAction(_("OpenInLocal"), ui->treeView);
    m_oRename = new QAction(QIcon::fromTheme("pyrenamer"), _("Rename"), ui->treeView);
    m_oDelete = new QAction(QIcon::fromTheme("edit-clear-symbolic"), _("Delete"), ui->treeView);
    m_oNewFolder = new QAction(QIcon::fromTheme("folder-new-symbolic"), _("NewFolder"), ui->treeView);
    m_oProperties = new QAction(_("Properties"), ui->treeView);

    m_oParent->setShortcut(Qt::Key_Backspace);
    m_oOpen->setShortcut(QKeySequence(Qt::Key_Return));
    m_oOpenLocal->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_Return));
    m_oRename->setShortcut(QKeySequence(Qt::Key_F2));
    m_oDelete->setShortcut(QKeySequence(Qt::Key_Delete));
    m_oNewFolder->setShortcut(QKeySequence(Qt::AltModifier + Qt::Key_N));
    m_oProperties->setShortcut(Qt::Key_F5);

    m_oMenu->addAction(m_oParent);
    m_oMenu->addSeparator();
    m_oMenu->addAction(m_oOpen);
    m_oMenu->addAction(m_oOpenLocal);
    m_oMenu->addSeparator();
    m_oMenu->addAction(m_oRename);
    m_oMenu->addAction(m_oDelete);
    m_oMenu->addAction(m_oNewFolder);
    m_oMenu->addSeparator();
    m_oMenu->addAction(m_oProperties);

    connect(m_oParent, SIGNAL(triggered(bool)), this, SLOT(slotsParent()));
    connect(m_oOpen, SIGNAL(triggered(bool)), this, SLOT(slotsOpen()));
    connect(m_oOpenLocal, SIGNAL(triggered(bool)), this, SLOT(slotsOpenLocal()));
    connect(m_oRename, SIGNAL(triggered(bool)), this, SLOT(slotsRename()));
    connect(m_oDelete, SIGNAL(triggered(bool)), this, SLOT(slotsDeleteFiles(bool)));
    connect(m_oNewFolder, SIGNAL(triggered(bool)), this, SLOT(slotsNewFolder(bool)));
    connect(m_oProperties, SIGNAL(triggered(bool)), this, SLOT(slotsProperties()));
}

/**
 * @brief 鼠标右键展现上下文菜单
 * @param pos 右键点击的位置
 */
void BurnData::slotsTreeMenuByRightKey(const QPoint &pos)
{
    QModelIndex curIndex = ui->treeView->indexAt(pos);      //当前点击的元素的index
    QModelIndex index = curIndex.sibling(curIndex.row(),0); //该行的第1列元素的index
    if (index.isValid())
    {
        m_oMenu->popup(QCursor::pos());//显示菜单
    }
}

/**
 * @brief 使用快捷键去展现上下文菜单
 */
void BurnData::slotsTreeMenuByShortcutKey()
{
    m_oMenu->popup(QCursor::pos());
}

void BurnData::linkEntry(QModelIndex idx)
{
    int level;
    int basic;
    QToolButton *btn;

    ui->labelWelcome->show();
    m_oLinks.at(0)->hide();
    if (!idx.isValid()) return;
    level = m_oModel->level(idx);
    if (0 == level)
    {
        for (int i = 0; i < m_oLinks.size(); ++i)
            m_oLinks.at(i)->hide();
        return;
    }
    ui->labelWelcome->hide();
    m_oLinks.at(0)->show();
    basic = ui->widget_3->width() / 8;
    if (m_oLinks.size() <= level)
    {
        qDebug()<<__LINE__<<__func__<<"BurnData";
        btn = new QToolButton(this);
        btn->setAutoRaise(true);
        btn->setText(m_oModel->data(idx).toString().append("/"));
        btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
        btn->setIcon(QIcon::fromTheme("folder-open"));
        btn->setProperty("useIconHighlightEffect", 0x8);
        if (btn->width() > basic && level > 5) btn->setFixedWidth(basic);
        if (level - 1 > 0) m_oLinks.last()->setIcon(QIcon::fromTheme("folder"));
        btn->setToolTip(btn->text());
        connect(btn, SIGNAL(clicked(bool)), this, SLOT(slotsLink()));
        m_oLinks << btn;
        m_oIndexes << idx;
        ui->link->insertWidget(level, m_oLinks.last());
        return;
    }
    for (int i = level; i < m_oLinks.size(); ++i)
        m_oLinks.at(i)->hide();
    m_oLinks.at(level)->setText(m_oModel->data(idx).toString().append("/"));
    m_oLinks.at(level)->setToolTip(m_oLinks.at(level)->text());
    if (m_oLinks.at(level)->width() > basic && level > 5)
        m_oLinks.at(level)->setFixedWidth(basic);
    m_oLinks.at(level)->setIcon(QIcon::fromTheme("folder-open"));
    m_oLinks.at(level)->show();
    m_oIndexes.replace(level, idx);
    if (--level) m_oLinks.at(level)->setIcon(QIcon::fromTheme("folder"));
}

void BurnData::slotsTip(bool b)
{
    if (b)
    {
        ui->layoutBurnData->setStretch(2, 1);
        ui->layoutBurnData->setStretch(3, 100);
        ui->tip->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
        ui->tip->setText(_("Please press button [Add] or drag file(s) to here for adding file(s)"));
        ui->tip->show();
    }
    else
    {
        ui->layoutBurnData->setStretch(2, 20);
        ui->layoutBurnData->setStretch(3, 1);
        ui->tip->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
        ui->tip->hide();                        //隐藏已选中*个文件
    }
}

void BurnData::slotsEntry(QModelIndex idx)
{
    //if (idx.column() == 0 && ".." != idx.data().toString()) return;
    idx = idx.siblingAtColumn(0);
    disconnect(FILTERRULES, SIGNAL(rangeAll(bool)), this, SLOT(slotsRangeChange(bool)));
    disconnect(FILTERRULES, SIGNAL(hidden(bool)), this, SLOT(slotsFilterHidden(bool)));
    disconnect(FILTERRULES, SIGNAL(broken(bool)), this, SLOT(slotsFilterBroken(bool)));
    disconnect(FILTERRULES, SIGNAL(repleace(bool)), this, SLOT(slotsRepleaceSymbolLinks(bool)));
    if (m_oModel->isUp(idx))
    {
        ui->treeView->setRootIndex(idx.parent().parent());
        linkEntry(idx.parent().parent());
        m_oModel->filter(idx.parent().parent());
        m_oAddIndex = idx.parent().parent();
    }
    else if (m_oModel->isFolder(idx))
    {
        ui->treeView->setRootIndex(idx);
        linkEntry(idx);
        m_oModel->filter(idx);
        m_oAddIndex = idx;
    }
    else
    {
        //ui->treeView->edit(idx);
    }
    ui->treeView->setCurrentIndex(QModelIndex());
    connect(FILTERRULES, SIGNAL(rangeAll(bool)), this, SLOT(slotsRangeChange(bool)));
    connect(FILTERRULES, SIGNAL(hidden(bool)), this, SLOT(slotsFilterHidden(bool)));
    connect(FILTERRULES, SIGNAL(broken(bool)), this, SLOT(slotsFilterBroken(bool)));
    connect(FILTERRULES, SIGNAL(repleace(bool)), this, SLOT(slotsRepleaceSymbolLinks(bool)));
}

void BurnData::slotsLink()
{
    int idx;
    QToolButton *btn;

    btn = qobject_cast<QToolButton *>(sender());
    idx = m_oLinks.indexOf(btn);
    if (-1 != idx){
        qDebug()<<__LINE__<<"BurnData"<<__func__<<idx;
        slotsEntry(m_oIndexes.at(idx));
    }
}

void BurnData::slotsSize(unsigned long size)
{
    QPalette pal;

    pal = ui->labelProjectSize->palette();
    if (m_oModel->checkSize())
        pal.setColor(QPalette::WindowText, Qt::green);
    else
        pal.setColor(QPalette::WindowText, Qt::red);
    ui->labelProjectSize->setPalette(pal);
    ui->labelProjectSize->setText(m_oModel->stringSize(size));
}

void BurnData::slotsSelectionChanged()
{
    QModelIndexList idxes;

    idxes = ui->treeView->selectionModel()->selectedRows();
    if (idxes.count() == 1)
    {
        if (m_oModel->checkAdd(idxes))
            m_oAddIndex = idxes.first();
    }
    else
    {
        m_oAddIndex = ui->treeView->rootIndex();
    }
    refresh();
}

void BurnData::slotsAddFiles(bool b)
{
    MultiSelectionFileDialog fd;
    QList<QUrl> list = fd.sidebarUrls();
    int sidebarNum = 8;//最大添加U盘数，可以自己定义
    QString home = QDir::homePath().section("/", -1, -1);
    QString mnt = "/media/" + home + "/";
    QDir mntDir(mnt);
    mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
    QFileInfoList filist = mntDir.entryInfoList();
    QList<QUrl> mntUrlList;
    for (int i = 0; i < sidebarNum && i < filist.size(); ++i) {
        QFileInfo fi = filist.at(i);
        if (fi.fileName() == "2691-6AB8")
                 continue;
        mntUrlList << QUrl("file://" + fi.filePath());
    }

    QFileSystemWatcher fsw(&fd);
    fsw.addPath("/media/" + home + "/");
    connect(&fsw, &QFileSystemWatcher::directoryChanged, &fd,
            [=, &sidebarNum, &mntUrlList, &list, &fd](const QString path) {
        QDir wmntDir(path);
        wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList wfilist = wmntDir.entryInfoList();
        mntUrlList.clear();
        for (int i = 0; i < sidebarNum && i < wfilist.size(); ++i) {
            QFileInfo fi = wfilist.at(i);
            if (fi.fileName() == "2691-6AB8")
                     continue;
            mntUrlList << QUrl("file://" + fi.filePath());
        }
        fd.setSidebarUrls(list + mntUrlList);
        fd.update();
    });

    connect(&fd, &QFileDialog::finished, &fd, [=, &list, &fd]() {
        fd.setSidebarUrls(list);
    });

    if (b)
    {
        qDebug()<<__func__<<__LINE__;
        fd.reset();
        fd.setExtendedSelection();
        fd.setDirectory(QDir::currentPath());
        fd.setWindowTitle(_("Burner") + " - " + _("Add File(s)"));
        fd.setWindowIcon(QIcon::fromTheme("burner"));
        fd.setSidebarUrls(list + mntUrlList);
        if (fd.exec())
            m_oModel->addDatasToIndex(fd.selectedFiles(), m_oAddIndex);
        ui->btnAdd->setChecked(false);
    }
	qDebug()<<__func__<<__LINE__<<m_oAddIndex<<ui->treeView->rootIndex();
    refresh();
}

void BurnData::slotsDeleteFiles(bool b)
{
    QModelIndexList idxes;
    QModelIndex idx;

    if (b || m_oDelete == sender())
    {
	//使用QMessageBox代替EXEC删除提示弹窗
        QScopedPointer<TipsChange> p(new TipsChange);
        if(p->question(_("Delete"), _("Delete file(s) selected?")))
        {
            ui->btnDelete->setChecked(false);
            return;
        }
        idxes = ui->treeView->selectionModel()->selectedRows();
        slotsFilterHidden(false);
        slotsFilterBroken(false);
        slotsRepleaceSymbolLinks(false);
        m_oModel->deleteDatasFromIndex(idxes, ui->treeView->rootIndex());
        m_oAddIndex = ui->treeView->rootIndex();
        ui->btnDelete->setChecked(false);
    }
    ui->treeView->setCurrentIndex(QModelIndex());
    refresh();
}

void BurnData::slotsCleanFiles(bool b)
{
    if (b)
    {
        QScopedPointer<TipsChange> p(new TipsChange);
//        if(p->question(_("Clean"), _("Clean all item(s) under %1?")
//                                .arg(ui->treeView->rootIndex().data().toString()))){
        if(p->question(_("Clean"), _("Clean all file(s)?"))){
            slotsFilterHidden(false);
            slotsFilterBroken(false);
            slotsRepleaceSymbolLinks(false);
            qDebug()<<__func__<<__LINE__;
            m_oModel->clearDatasUnderIndex(ui->treeView->rootIndex());
        }
        ui->btnClean->setChecked(false);
    }
    refresh();
}

void BurnData::slotsNewFolder(bool b)
{
    QString folderName;
    bool inputed;

    if (b || m_oNewFolder == sender())
    {
        do
        {
            InputChange inputchange;
            inputed = inputchange.input(folderName, _("NewFolder"), _("Please input new folder name."), _("NewFolder"));
            if (!inputed) break;
            ui->btnNewFolder->setChecked(false);
            if (folderName.trimmed().isEmpty())
            {
                EXEC->error(_("NewFolder") + _("Empty Name"),
                            _("New Folder cannot be named with empty."));
                continue;
            }
            if (folderName.contains("/"))
            {
                EXEC->error(_("NewFolder") + _("Empty Name"),
                            _("New Folder cannot be named with ""/""."));
                continue;
            }
            if (folderName.length() > 103)
            {
                EXEC->error(_("NewFolder") + _("Name Too Long"),
                            _("Need less than 103 unicode charset for naming new folder."));
                continue;
            }
            if (m_oModel->duplicatedName(folderName, m_oAddIndex))
            {
                EXEC->error(_("NewFolder") + _("Duplicate Name"),
                            _("There is a item named by %1").arg(folderName));
                continue;
            }
            if (inputed) break;
        } while (true);
        if (inputed)
            m_oModel->addEmptyFolder(folderName.trimmed(), m_oAddIndex);
        ui->btnNewFolder->setChecked(false);
    }
    refresh();
}

void BurnData::slotsRangeChange(bool b)
{

    if (b) {
        qDebug()<<"BurnData隐藏"<<__func__<<__LINE__<<b;
        m_oModel->filter();
    }
    else{
        qDebug()<<"BurnData隐藏"<<__func__<<__LINE__<<b;
        m_oModel->filter(ui->treeView->rootIndex());
    }
}
#include "../data/datadirectory.h"
void BurnData::slotsFilterHidden(bool b)
{
    QList<void *> datas;
    QModelIndex idx;

    DataDirectory::setFilterHidden(b);
    if (b)
    {
        if (CFG->get("FilterFile", "range", true).toBool())
        {
            qDebug()<<"BurnData隐藏"<<__func__<<__LINE__<<b;
            CFG->set("FilterFile","hidden",b);
            m_oModel->doFilterHidden();
        }
        else
        {
            qDebug()<<"BurnData隐藏"<<__func__<<__LINE__<<b;
            m_oModel->doFilterHidden(ui->treeView->rootIndex());
        }
    }

    else
    {
        idx = QModelIndex();
        if (!VIEWFILTERFILE->isHidden() &&
                (VIEWFILTERFILE->currentIndex() != m_oModel->index())) return;

        if (CFG->get("FilterFile", "range", true).toBool()){
            CFG->set("FilterFile","hidden",b);
            qDebug()<<"BurnData恢复"<<__func__<<__LINE__<<b;
            datas = VIEWFILTERFILE->recoveryHiddenData(m_oModel->index(), m_oModel->level());

        }
        else
        {
            qDebug()<<"BurnData恢复"<<__func__<<__LINE__<<b;
            idx = ui->treeView->rootIndex();
            datas = VIEWFILTERFILE->recoveryHiddenData(m_oModel->index(), m_oModel->level(idx));
        }
        m_oModel->doRecoveryHidden(datas, idx);
    }
    update();
    refresh();
}

void BurnData::slotsFilterBroken(bool b)
{
    QList<void *> datas;
    QModelIndex idx;

    DataDirectory::setFilterBrokenSymbolLinks(b);
    if (b)
    {
        if (CFG->get("FilterFile", "range", true).toBool()){
            qDebug()<<__LINE__<<__func__<<b;
            CFG->set("FilterFile","broken",b);
            m_oModel->doFilterBroken();
        }else{
            m_oModel->doFilterBroken(ui->treeView->rootIndex());
        }
    }
    else
    {
        idx = QModelIndex();
        if (CFG->get("FilterFile", "range", true).toBool()){
            CFG->set("FilterFile","broken",b);
            datas = VIEWFILTERFILE->recoveryBrokenData(m_oModel->index(), m_oModel->level());
        }
        else
        {
            idx = ui->treeView->rootIndex();
            datas = VIEWFILTERFILE->recoveryBrokenData(m_oModel->index(), m_oModel->level(idx));
        }
        m_oModel->doRecoveryBroken(datas, idx);
    }
    update();
    refresh();
}

void BurnData::slotsRepleaceSymbolLinks(bool b)
{
    QList<void *> datas;

    DataDirectory::setRepleaceSymbolLinks(b);
    if (b)
    {
        if (CFG->get("FilterFile", "range", true).toBool()){
            qDebug()<<__LINE__<<__func__<<b;
            CFG->set("FilterFile","Repleace",b);
            m_oModel->doFilterRepleace();
        }else{
            m_oModel->doFilterRepleace(ui->treeView->rootIndex());
        }

    }
    else
    {
        if (CFG->get("FilterFile", "range", true).toBool()){
            CFG->set("FilterFile","Repleace",b);
            datas = VIEWFILTERFILE->recoveryRepleaceData(m_oModel->index(), m_oModel->level());
        }else{
            datas = VIEWFILTERFILE->recoveryRepleaceData(m_oModel->index(), m_oModel->level(ui->treeView->rootIndex()));
        }
        m_oModel->doRecoveryRepleace(datas);
    }
    update();
    refresh();
}

void BurnData::slotsParent()
{
    if (ui->treeView->rootIndex().parent().isValid()){
        //ui->treeView->setRootIndex(ui->treeView->rootIndex().parent());
        slotsEntry(ui->treeView->rootIndex().parent());
    }
    refresh();
}

void BurnData::slotsOpen()
{
    if (".." == ui->treeView->selectionModel()->selectedIndexes().first().siblingAtColumn(0).data().toString()){
        slotsParent();

    }else{
        slotsEntry(ui->treeView->selectionModel()->selectedIndexes().first());
       // ui->treeView->setRootIndex(ui->treeView->selectionModel()->selectedIndexes().first());
      //  linkEntry(ui->treeView->selectionModel()->selectedIndexes().first());

    }
  //  refresh();
}

void BurnData::slotsOpenLocal()
{
    QModelIndex idx;

    if (".." == ui->treeView->selectionModel()->selectedIndexes().first().siblingAtColumn(0).data().toString())
        idx = ui->treeView->rootIndex();
    else
        idx = ui->treeView->selectionModel()->selectedIndexes().first();
    m_oOpenFile->setFile(idx.siblingAtColumn(3).data().toString());
    m_oOpenFile->exec();
}

void BurnData::slotsRename()
{
    QModelIndex idx;

    idx = ui->treeView->selectionModel()->selectedIndexes().first().siblingAtColumn(0);
    ui->treeView->edit(idx);
}

void BurnData::slotsProperties()
{
    QString cmd;
    QModelIndex idx;

    idx = ui->treeView->selectionModel()->selectedIndexes().first();
    cmd = QString("peony -p \"%1\"").arg(idx.siblingAtColumn(3).data().toString());
    ::system(cmd.toUtf8().constData());
}

BurnData::~BurnData()
{
    delete ui;
    if (m_oMenu) {
        delete m_oMenu;
        m_oMenu = nullptr;
    }
    if (m_oParent) {
        delete m_oParent;
        m_oParent = nullptr;
    }
    if (m_oOpen) {
        delete m_oOpen;
        m_oOpen = nullptr;
    }
    if (m_oOpenLocal) {
        delete m_oOpenLocal;
        m_oOpenLocal = nullptr;
    }
    if (m_oRename) {
        delete m_oRename;
        m_oRename = nullptr;
    }
    if (m_oDelete) {
        delete m_oDelete;
        m_oDelete = nullptr;
    }
    if (m_oNewFolder) {
        delete m_oNewFolder;
        m_oNewFolder = nullptr;
    }
    if (m_oProperties) {
        delete m_oProperties;
        m_oProperties = nullptr;
    }
}

MyTreeView::MyTreeView(QWidget *parent)
    :   QTreeView(parent)
{

}

void MyTreeView::keyPressEvent(QKeyEvent *event)
{
//    qDebug() << "MyTreeView::keyPressEvent  " << event->key();
    QWidget::keyPressEvent(event);
}

void MyTreeView::mousePressEvent(QMouseEvent *event)
{
//    qDebug() << "KyTreeView::mousePressEvent鼠标事件";
    if(event->button() == Qt::RightButton) {
//        qDebug() << "KyTreeView::mousePressEvent右键按下";
        emit g_user_signal->sigMenuByRightMousePress();
        event->accept();
        return;
    }
    QTreeView::mousePressEvent(event);
}
