<commit_before>#include <QtGlobal>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include <QHeaderView>
#include <QDesktopServices>
#include <QEvent>
#include <QShowEvent>
#include <QHideEvent>
#include <QInputDialog>
#include <Qt>

#include "utils/utils.h"
#include "seafile-applet.h"
#include "settings-mgr.h"
#include "account-mgr.h"
#include "rpc/rpc-client.h"
#include "rpc/local-repo.h"
#include "download-repo-dialog.h"
#include "clone-tasks-dialog.h"
#include "repo-item.h"
#include "repo-item-delegate.h"
#include "repo-tree-model.h"
#include "repo-detail-dialog.h"
#include "utils/paint-utils.h"
#include "repo-service.h"
#include "auto-login-service.h"

#include "filebrowser/file-browser-manager.h"
#include "filebrowser/file-browser-dialog.h"
#include "utils/utils-mac.h"
#include "filebrowser/tasks.h"
#include "filebrowser/progress-dialog.h"
#include "ui/set-repo-password-dialog.h"
#include "ui/private-share-dialog.h"
#include "ui/check-repo-root-perm-dialog.h"

#include "repo-tree-view.h"

namespace {

const char *kRepoTreeViewSettingsGroup = "RepoTreeView";
const char *kRepoTreeViewSettingsExpandedCategories = "expandedCategories";
const char *kSyncIntervalProperty = "sync-interval";

// A Helper Class to copy file
//
class FileCopyHelper : public QRunnable {
public:
    FileCopyHelper(const QString &source, const QString &target,
                   RepoTreeView *parent)
    : source_(source),
      target_(target),
      parent_(parent) {
    }
signals:
    void success(bool);
private:
    void run() {
        if (!QFile::copy(source_, target_)) {
            // cannot do GUI operations in this thread
            // callback to the main thread
            QMetaObject::invokeMethod(parent_, "copyFileFailed");
        }
    }
    bool autoDelete() {
        return true;
    }
    const QString source_;
    const QString target_;
    RepoTreeView *parent_;
};

FileCopyHelper* copyFile(const QString &source, const QString &target, RepoTreeView *parent) {
      FileCopyHelper* helper = new FileCopyHelper(source, target, parent);
      QThreadPool *pool = QThreadPool::globalInstance();
      pool->start(helper);
      return helper;
}

} // anonymous namespace

static ServerRepo selected_repo_;
// TODO save localrepo as well to avoid many copys

RepoTreeView::RepoTreeView(QWidget *parent)
    : QTreeView(parent)
{
    header()->hide();
    createActions();

    // We draw the indicator ourselves
    setIndentation(0);
    // We handle the click oursevles
    setExpandsOnDoubleClick(false);

    connect(this, SIGNAL(clicked(const QModelIndex&)),
            this, SLOT(onItemClicked(const QModelIndex&)));

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
            this, SLOT(onItemDoubleClicked(const QModelIndex&)));
#if defined(Q_OS_MAC)
    this->setAttribute(Qt::WA_MacShowFocusRect, 0);
#endif

    loadExpandedCategries();
    connect(qApp, SIGNAL(aboutToQuit()),
            this, SLOT(saveExpandedCategries()));
    connect(seafApplet->accountManager(), SIGNAL(beforeAccountChanged()),
            this, SLOT(saveExpandedCategries()));
    connect(seafApplet->accountManager(), SIGNAL(accountsChanged()),
            this, SLOT(loadExpandedCategries()));
    connect(seafApplet->settingsManager(), SIGNAL(autoSyncChanged(bool)),
            this, SLOT(update()));

    setAcceptDrops(true);
    setDefaultDropAction(Qt::CopyAction);
    // setAlternatingRowColors(true);
    setDropIndicatorShown(true);

    current_drop_target_ = QModelIndex();
    previous_drop_target_ = QModelIndex();
}

void RepoTreeView::loadExpandedCategries()
{
    Account account = seafApplet->accountManager()->currentAccount();
    if (!account.isValid()) {
        return;
    }
    expanded_categroies_.clear();
    QSettings settings;
    settings.beginGroup(kRepoTreeViewSettingsGroup);
    QString key = QString(kRepoTreeViewSettingsExpandedCategories) + "-" + account.getSignature();
    if (settings.contains(key)) {
        QString cats = settings.value(key, "").toString();
        expanded_categroies_ = QSet<QString>::fromList(cats.split("\t", QString::SkipEmptyParts));
    } else {
        // Expand "recent updated" on first use
        expanded_categroies_.insert(tr("Recently Updated"));
    }
    settings.endGroup();
}

void RepoTreeView::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint pos = event->pos();
    QModelIndex index = indexAt(pos);
    if (!index.isValid()) {
        // Not clicked at a repo item
        return;
    }

    QStandardItem *item = getRepoItem(index);
    if (!item || item->type() != REPO_ITEM_TYPE) {
        return;
    }
    updateRepoActions();
    QMenu *menu = prepareContextMenu((RepoItem *)item);
    pos = viewport()->mapToGlobal(pos);
    menu->exec(pos);
    menu->deleteLater();
}

QMenu* RepoTreeView::prepareContextMenu(const RepoItem *item)
{
    QMenu *menu = new QMenu(this);
    if (item->localRepo().isValid()) {
        menu->addAction(open_local_folder_action_);
    }

    if (item->repoDownloadable()) {
        menu->addAction(download_action_);
    }

    menu->addAction(view_on_web_action_);
    menu->addAction(open_in_filebrowser_action_);

    if (item->repo().isSharedRepo()) {
        menu->addAction(unshare_action_);
    }

    const Account& account = seafApplet->accountManager()->currentAccount();
    if (account.isPro() && account.username == item->repo().owner) {
        menu->addSeparator();
        menu->addAction(share_repo_to_user_action_);
        menu->addAction(share_repo_to_group_action_);
        menu->addSeparator();
    }

    if (item->localRepo().isValid()) {
        menu->addSeparator();
        menu->addAction(toggle_auto_sync_action_);
        menu->addAction(sync_now_action_);
        menu->addAction(set_sync_interval_action_);
        menu->addSeparator();
    }

    menu->addAction(show_detail_action_);

    if (item->cloneTask().isCancelable()) {
        menu->addAction(cancel_download_action_);
    }
    if (item->localRepo().isValid()) {
        menu->addAction(unsync_action_);
        menu->addAction(resync_action_);
    }

    return menu;<commit_msg>Hide the "leave share" menu item for now<commit_after>#include <QtGlobal>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include <QHeaderView>
#include <QDesktopServices>
#include <QEvent>
#include <QShowEvent>
#include <QHideEvent>
#include <QInputDialog>
#include <Qt>

#include "utils/utils.h"
#include "seafile-applet.h"
#include "settings-mgr.h"
#include "account-mgr.h"
#include "rpc/rpc-client.h"
#include "rpc/local-repo.h"
#include "download-repo-dialog.h"
#include "clone-tasks-dialog.h"
#include "repo-item.h"
#include "repo-item-delegate.h"
#include "repo-tree-model.h"
#include "repo-detail-dialog.h"
#include "utils/paint-utils.h"
#include "repo-service.h"
#include "auto-login-service.h"

#include "filebrowser/file-browser-manager.h"
#include "filebrowser/file-browser-dialog.h"
#include "utils/utils-mac.h"
#include "filebrowser/tasks.h"
#include "filebrowser/progress-dialog.h"
#include "ui/set-repo-password-dialog.h"
#include "ui/private-share-dialog.h"
#include "ui/check-repo-root-perm-dialog.h"

#include "repo-tree-view.h"

namespace {

const char *kRepoTreeViewSettingsGroup = "RepoTreeView";
const char *kRepoTreeViewSettingsExpandedCategories = "expandedCategories";
const char *kSyncIntervalProperty = "sync-interval";

// A Helper Class to copy file
//
class FileCopyHelper : public QRunnable {
public:
    FileCopyHelper(const QString &source, const QString &target,
                   RepoTreeView *parent)
    : source_(source),
      target_(target),
      parent_(parent) {
    }
signals:
    void success(bool);
private:
    void run() {
        if (!QFile::copy(source_, target_)) {
            // cannot do GUI operations in this thread
            // callback to the main thread
            QMetaObject::invokeMethod(parent_, "copyFileFailed");
        }
    }
    bool autoDelete() {
        return true;
    }
    const QString source_;
    const QString target_;
    RepoTreeView *parent_;
};

FileCopyHelper* copyFile(const QString &source, const QString &target, RepoTreeView *parent) {
      FileCopyHelper* helper = new FileCopyHelper(source, target, parent);
      QThreadPool *pool = QThreadPool::globalInstance();
      pool->start(helper);
      return helper;
}

} // anonymous namespace

static ServerRepo selected_repo_;
// TODO save localrepo as well to avoid many copys

RepoTreeView::RepoTreeView(QWidget *parent)
    : QTreeView(parent)
{
    header()->hide();
    createActions();

    // We draw the indicator ourselves
    setIndentation(0);
    // We handle the click oursevles
    setExpandsOnDoubleClick(false);

    connect(this, SIGNAL(clicked(const QModelIndex&)),
            this, SLOT(onItemClicked(const QModelIndex&)));

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
            this, SLOT(onItemDoubleClicked(const QModelIndex&)));
#if defined(Q_OS_MAC)
    this->setAttribute(Qt::WA_MacShowFocusRect, 0);
#endif

    loadExpandedCategries();
    connect(qApp, SIGNAL(aboutToQuit()),
            this, SLOT(saveExpandedCategries()));
    connect(seafApplet->accountManager(), SIGNAL(beforeAccountChanged()),
            this, SLOT(saveExpandedCategries()));
    connect(seafApplet->accountManager(), SIGNAL(accountsChanged()),
            this, SLOT(loadExpandedCategries()));
    connect(seafApplet->settingsManager(), SIGNAL(autoSyncChanged(bool)),
            this, SLOT(update()));

    setAcceptDrops(true);
    setDefaultDropAction(Qt::CopyAction);
    // setAlternatingRowColors(true);
    setDropIndicatorShown(true);

    current_drop_target_ = QModelIndex();
    previous_drop_target_ = QModelIndex();
}

void RepoTreeView::loadExpandedCategries()
{
    Account account = seafApplet->accountManager()->currentAccount();
    if (!account.isValid()) {
        return;
    }
    expanded_categroies_.clear();
    QSettings settings;
    settings.beginGroup(kRepoTreeViewSettingsGroup);
    QString key = QString(kRepoTreeViewSettingsExpandedCategories) + "-" + account.getSignature();
    if (settings.contains(key)) {
        QString cats = settings.value(key, "").toString();
        expanded_categroies_ = QSet<QString>::fromList(cats.split("\t", QString::SkipEmptyParts));
    } else {
        // Expand "recent updated" on first use
        expanded_categroies_.insert(tr("Recently Updated"));
    }
    settings.endGroup();
}

void RepoTreeView::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint pos = event->pos();
    QModelIndex index = indexAt(pos);
    if (!index.isValid()) {
        // Not clicked at a repo item
        return;
    }

    QStandardItem *item = getRepoItem(index);
    if (!item || item->type() != REPO_ITEM_TYPE) {
        return;
    }
    updateRepoActions();
    QMenu *menu = prepareContextMenu((RepoItem *)item);
    pos = viewport()->mapToGlobal(pos);
    menu->exec(pos);
    menu->deleteLater();
}

QMenu* RepoTreeView::prepareContextMenu(const RepoItem *item)
{
    QMenu *menu = new QMenu(this);
    if (item->localRepo().isValid()) {
        menu->addAction(open_local_folder_action_);
    }

    if (item->repoDownloadable()) {
        menu->addAction(download_action_);
    }

    menu->addAction(view_on_web_action_);
    menu->addAction(open_in_filebrowser_action_);

    // if (item->repo().isSharedRepo()) {
    //     menu->addAction(unshare_action_);
    // }

    const Account& account = seafApplet->accountManager()->currentAccount();
    if (account.isPro() && account.username == item->repo().owner) {
        menu->addSeparator();
        menu->addAction(share_repo_to_user_action_);
        menu->addAction(share_repo_to_group_action_);
        menu->addSeparator();
    }

    if (item->localRepo().isValid()) {
        menu->addSeparator();
        menu->addAction(toggle_auto_sync_action_);
        menu->addAction(sync_now_action_);
        menu->addAction(set_sync_interval_action_);
        menu->addSeparator();
    }

    menu->addAction(show_detail_action_);

    if (item->cloneTask().isCancelable()) {
        menu->addAction(cancel_download_action_);
    }
    if (item->localRepo().isValid()) {
        menu->addAction(unsync_action_);
        menu->addAction(resync_action_);
    }

    return menu;
{'fraction_non_alphanumeric': 0.13719168144446237, 'fraction_numerical': 0.0008060615831049493, 'mean_word_length': 3.748182166092614, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4480334', 'n_tokens_mistral': 3900, 'n_tokens_neox': 3886, 'n_words': 722}