void FileBrowserDialog::onDirClicked(const SeafDirent& dir)
{
    const QString& path = ::pathJoin(current_path_, dir.name);
    backward_history_.push(current_path_);
    forward_history_.clear();
    enterPath(path);
}
FileBrowserDialog::FileBrowserDialog(const Account &account, const ServerRepo& repo, const QString &path, QWidget *parent)
    : QDialog(parent),
      account_(account),
      repo_(repo),
      current_path_(path),
      current_readonly_(repo_.readonly)
{
    current_lpath_ = current_path_.split('/');

    data_mgr_ = new DataManager(account_);

    setWindowTitle(tr("Cloud File Browser"));
    setWindowIcon(QIcon(":/images/seafile.png"));
    setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::Dialog)
#if !defined(Q_OS_MAC)
                   | Qt::FramelessWindowHint
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
                   | Qt::WindowMinimizeButtonHint
#endif
                   | Qt::Window);

    resizer_ = new QSizeGrip(this);
    resizer_->resize(resizer_->sizeHint());
    setAttribute(Qt::WA_TranslucentBackground, true);

    createTitleBar();
    createToolBar();
    createStatusBar();
    createLoadingFailedView();
    createFileTable();

    QWidget* widget = new QWidget;
    widget->setObjectName("mainWidget");
    QVBoxLayout* layout = new QVBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    setLayout(layout);
    layout->addWidget(widget);

    QVBoxLayout *vlayout = new QVBoxLayout;
    vlayout->setContentsMargins(1, 0, 1, 0);
    vlayout->setSpacing(0);
    widget->setLayout(vlayout);

    stack_ = new QStackedWidget;
    stack_->insertWidget(INDEX_LOADING_VIEW, loading_view_);
    stack_->insertWidget(INDEX_TABLE_VIEW, table_view_);
    stack_->insertWidget(INDEX_LOADING_FAILED_VIEW, loading_failed_view_);
    stack_->setContentsMargins(0, 0, 0, 0);

    vlayout->addWidget(header_);
    vlayout->addWidget(toolbar_);
    vlayout->addWidget(stack_);
    vlayout->addWidget(status_bar_);

#ifdef Q_OS_MAC
    header_->setVisible(false);
#endif

    // this <--> table_view_
    connect(table_view_, SIGNAL(direntClicked(const SeafDirent&)),
            this, SLOT(onDirentClicked(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntSaveAs(const QList<const SeafDirent*>&)),
            this, SLOT(onDirentSaveAs(const QList<const SeafDirent*>&)));
    connect(table_view_, SIGNAL(direntLock(const SeafDirent&)),
            this, SLOT(onGetDirentLock(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntRename(const SeafDirent&)),
            this, SLOT(onGetDirentRename(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntRemove(const SeafDirent&)),
            this, SLOT(onGetDirentRemove(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntRemove(const QList<const SeafDirent*> &)),
            this, SLOT(onGetDirentRemove(const QList<const SeafDirent*> &)));
    connect(table_view_, SIGNAL(direntShare(const SeafDirent&)),
            this, SLOT(onGetDirentShare(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntShareSeafile(const SeafDirent&)),
            this, SLOT(onGetDirentShareSeafile(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntUpdate(const SeafDirent&)),
            this, SLOT(onGetDirentUpdate(const SeafDirent&)));
    connect(table_view_, SIGNAL(direntPaste()),
            this, SLOT(onGetDirentsPaste()));
    connect(table_view_, SIGNAL(cancelDownload(const SeafDirent&)),
            this, SLOT(onCancelDownload(const SeafDirent&)));
    connect(table_view_, SIGNAL(syncSubdirectory(const QString&)),
            this, SLOT(onGetSyncSubdirectory(const QString &)));

    //dirents <--> data_mgr_
    connect(data_mgr_, SIGNAL(getDirentsSuccess(bool, const QList<SeafDirent>&)),
            this, SLOT(onGetDirentsSuccess(bool, const QList<SeafDirent>&)));
    connect(data_mgr_, SIGNAL(getDirentsFailed(const ApiError&)),
            this, SLOT(onGetDirentsFailed(const ApiError&)));

    //create <--> data_mgr_
    connect(data_mgr_, SIGNAL(createDirectorySuccess(const QString&)),
            this, SLOT(onDirectoryCreateSuccess(const QString&)));
    connect(data_mgr_, SIGNAL(createDirectoryFailed(const ApiError&)),
            this, SLOT(onDirectoryCreateFailed(const ApiError&)));

    //lock <--> data_mgr_
    connect(data_mgr_, SIGNAL(lockFileSuccess(const QString&, bool)),
            this, SLOT(onFileLockSuccess(const QString&, bool)));
    connect(data_mgr_, SIGNAL(lockFileFailed(const ApiError&)),
            this, SLOT(onFileLockFailed(const ApiError&)));

    //rename <--> data_mgr_
    connect(data_mgr_, SIGNAL(renameDirentSuccess(const QString&, const QString&)),
            this, SLOT(onDirentRenameSuccess(const QString&, const QString&)));
    connect(data_mgr_, SIGNAL(renameDirentFailed(const ApiError&)),
            this, SLOT(onDirentRenameFailed(const ApiError&)));

    //remove <--> data_mgr_
    connect(data_mgr_, SIGNAL(removeDirentSuccess(const QString&)),
            this, SLOT(onDirentRemoveSuccess(const QString&)));
    connect(data_mgr_, SIGNAL(removeDirentFailed(const ApiError&)),
            this, SLOT(onDirentRemoveFailed(const ApiError&)));

    //share <--> data_mgr_
    connect(data_mgr_, SIGNAL(shareDirentSuccess(const QString&)),
            this, SLOT(onDirentShareSuccess(const QString&)));
    connect(data_mgr_, SIGNAL(shareDirentFailed(const ApiError&)),
            this, SLOT(onDirentShareFailed(const ApiError&)));

    //copy <--> data_mgr_
    connect(data_mgr_, SIGNAL(copyDirentsSuccess()),
            this, SLOT(onDirentsCopySuccess()));
    connect(data_mgr_, SIGNAL(copyDirentsFailed(const ApiError&)),
            this, SLOT(onDirentsCopyFailed(const ApiError&)));

    //move <--> data_mgr_
    connect(data_mgr_, SIGNAL(moveDirentsSuccess()),
            this, SLOT(onDirentsMoveSuccess()));
    connect(data_mgr_, SIGNAL(moveDirentsFailed(const ApiError&)),
            this, SLOT(onDirentsMoveFailed(const ApiError&)));

    //subrepo <-->data_mgr_
    connect(data_mgr_, SIGNAL(createSubrepoSuccess(const ServerRepo &)),
            this, SLOT(onCreateSubrepoSuccess(const ServerRepo &)));
    connect(data_mgr_, SIGNAL(createSubrepoFailed(const ApiError&)),
            this, SLOT(onCreateSubrepoFailed(const ApiError&)));

    connect(AutoUpdateManager::instance(), SIGNAL(fileUpdated(const QString&, const QString&)),
            this, SLOT(onFileAutoUpdated(const QString&, const QString&)));

    // QTimer::singleShot(0, this, SLOT(fetchDirents()));

    enterPath("/");
}
void FileBrowserDialog::init()
{
    enterPath(current_path_);
}