void RepoTreeModel::checkGroupRepo(const ServerRepo& repo)
{
    QStandardItem *root = invisibleRootItem();
    RepoCategoryItem *group = NULL;

    int row, n = root->rowCount();

    // First find for create the group
    // Starts from row 2 because the first two rows are "My Libraries" and "Shared Libraries"
    for (row = 2; row < n; row ++) {
        RepoCategoryItem *item = (RepoCategoryItem *)(root->child(row));
        if (item->groupId() == repo.group_id) {
            group = item;
            break;
        }
    }
    if (!group) {
        group = new RepoCategoryItem(repo.group_name, repo.group_id);
        appendRow(group);
    }

    // Find the repo in this group
    n = group->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(group->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // Current repo not in this group yet
    RepoItem *item = new RepoItem(repo);
    group->appendRow(item);
}
void RepoTreeModel::removeReposDeletedOnServer(const std::vector<ServerRepo>& repos)
{
    int i, n;
    DeleteRepoData data;
    n = repos.size();
    for (i = 0; i < n; i++) {
        const ServerRepo& repo = repos[i];
        data.map.insert(repo.id, &repo);
    }

    forEachRepoItem(&RepoTreeModel::collectDeletedRepos, (void *)&data);

    QListIterator<RepoItem*> iter(data.itemsToDelete);
    while(iter.hasNext()) {
        RepoItem *item = iter.next();

        const ServerRepo& repo = item->repo();

        qDebug("remove repo %s(%s) from \"%s\"\n",
               toCStr(repo.name), toCStr(repo.id),
               toCStr(((RepoCategoryItem*)item->parent())->name()));

        item->parent()->removeRow(item->row());
    }
}
void RepoTreeView::onItemDoubleClicked(const QModelIndex& index)
{
    QStandardItem *item = getRepoItem(index);
    if (!item) {
        return;
    }
    if (item->type() == REPO_ITEM_TYPE) {
        RepoItem *it = (RepoItem *)item;
        const LocalRepo& local_repo = it->localRepo();
        if (local_repo.isValid()) {
            // open local folder for downloaded repo
            QDesktopServices::openUrl(QUrl::fromLocalFile(local_repo.worktree));
        } else {
            // open seahub repo page for not downloaded repo
            // if (seafApplet->isPro()) {
            FileBrowserDialog* dialog = new FileBrowserDialog(it->repo(), this);
            const QRect screen = QApplication::desktop()->screenGeometry();
            dialog->setAttribute(Qt::WA_DeleteOnClose, true);
            dialog->show();
            dialog->move(screen.center() - dialog->rect().center());
            dialog->raise();
            // } else {
            //     const Account& account = seafApplet->accountManager()->accounts()[0];
            //     if (account.isValid()) {
            //         QUrl url = account.getAbsoluteUrl("repo/" + it->repo().id);
            //         QDesktopServices::openUrl(url);
            //     }
            // }
        }
    }
}
Beispiel #4
0
/** Populate the RepoModel with RepoItem entries that reproduce the hierarchical 
 *  organization of ScriptRepository entries. 
 * 
 * It will get the information from ScriptRepository from the listFiles, which means, 
 * that it will reconstruct the hierarchical organization of the files and folders
 * through the list of strings with the relative path of each entry. 
 * 
 * @param root: The RepoItem root 
 */
void RepoModel::setupModelData(RepoItem *root)
{

  QStringList lines;
  // check server for updates to repository
  repo_ptr->check4Update();
  // get the list of entries inside the scriptrepository
  std::vector<std::string> list = repo_ptr->listFiles();
  
  // auxiliary list of pointers to repoitem that are related to folders
  QList<RepoItem*> parents;
  // the first one will always be the root
  parents << root;

  
  QString last_directory = "";
  
  //FOREACH entry in LISTFILES
  for (unsigned int number = 0; number < list.size(); number++) {
    // folder or file inside the repository
    QString lineData = QString::fromStdString(list[number]);

    
    // Read the column data from the rest of the line.      
    QStringList pathStrings = lineData.split("/");
    // separate the folder and the current entry (folder or file)
    QString current_file = pathStrings.last(); 
    QString folder = ""; 
    pathStrings.removeLast(); 
    if (pathStrings.size() > 0)
      folder = pathStrings.join("/"); 
    
    // get parent for this entry
    RepoItem * parent = getParent(folder, parents);    
    // a new folder has started
    if (parent == root){
      // this test is just for the sake of performance, to reduce the numbers of parents
      parents.clear(); 
      parents << root;
    }
    
    // check if the current entry is a directory
    if (repo_ptr->info(lineData.toStdString()).directory){
      // directories will be appended to parents list
      RepoItem * aux = new RepoItem(current_file, lineData, parent); 
      parent->appendChild(aux); 
      parents << aux;                           
    }else{
      // files will just be created and appended to the parent
      parent->appendChild(new RepoItem(current_file, lineData, parent));
      
    }
    
  }
  
}
Beispiel #5
0
/** Return the description of the file for a defined entry
 **/
QString RepoModel::fileDescription(const QModelIndex & index) {
    RepoItem * item = static_cast<RepoItem*>(index.internalPointer());
    if (!item)
        return "";
    QString desc;
    try {
        desc = QString::fromStdString(repo_ptr->description(item->path().toStdString()));
    } catch(...) {
        // just ignore
    }
    return desc;
}
Beispiel #6
0
QString RepoModel::author(const QModelIndex & index) {
    RepoItem * item = static_cast<RepoItem*>(index.internalPointer());
    QString author = "Not defined";
    if (!item)
        return author;
    try {
        author = QString::fromStdString(repo_ptr->info(item->path().toStdString()).author);
    } catch(...) {
        // just ignore
    }
    return author;
}
Beispiel #7
0
/** Return the operative system file path if it exists.
    otherwise it returns an empty string
    @param index: to find the entry
    @return The operative system path or empty string
*/
QString RepoModel::filePath(const QModelIndex & index) {
    RepoItem * item = static_cast<RepoItem*>(index.internalPointer());
    //   qDebug() << "Get file path from : " <<  item->path()<< endl;
    Mantid::API::SCRIPTSTATUS state = repo_ptr->fileStatus(item->path().toStdString());

    if (state == Mantid::API::REMOTE_ONLY)
        return "";
    Mantid::API::ScriptInfo info = repo_ptr->fileInfo(item->path().toStdString());
    if (info.directory)
        return "";
    QString path = repo_path + "/" + item->path();
    return path;
}
Beispiel #8
0
/** Count how many file/folders are direct children of the given folder,
 * through the abstraction of QModelIndex.
 *
 * @param parent: the index to the folder.
 * @return the number of children of the given folder.
 */
int RepoModel::rowCount(const QModelIndex &parent) const
{
    RepoItem *parentItem;

    if (parent.column() > 0)
        return 0; // there are rows defined only of the column 0

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<RepoItem*>(parent.internalPointer());
    // return the number of children
    return parentItem->childCount();
}
Beispiel #9
0
/** Provide the parent of a given entry, through the QModelIndex abstraction.
 *
 * @param index: The QModelIndex that identifies one entry.
 * @return A QModelIndex that indentifies the parent of the given index.
 */
QModelIndex RepoModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();
    // the child is the RepoItem pointed by the index.
    RepoItem *childItem = static_cast<RepoItem*>(index.internalPointer());
    // the parent is the parent of the RepoItem.
    RepoItem *parentItem = childItem->parent();
    // the root item does not have a parent
    if (parentItem == rootItem)
        return QModelIndex();
    // create the index and return
    return createIndex(parentItem->row(), 0, parentItem);
}
Beispiel #10
0
/**Auxiliary method to help setupModelData to populate all the
   entries of RepoModel.

   For any entry of ScriptRepository should have a parent (by definition, all the entries
   are children of the root entry). Besides, given an entry, if the path contains a '/' this
   means that the entry is child of one folder. And all the folders are parents by definition.

   So, the idea of this getParent is that given a folder name, it must be related to a RepoItem
   that is a parent. If it does not exists, it should be created.

   @param folder: relative path inside the repository for the folder.
   @param parents Reference to the list of parents
   @return Pointer to the RepoItem related to the given folder.

**/
RepoModel::RepoItem * RepoModel::getParent(const QString & folder, QList<RepoItem*>&parents) {
    // in order to speed the algorithm, check if the
    // folder is the same of the last folder.
    if (parents.last()->path() == folder)
        return parents.last();

    // try to find this
    if (folder.isEmpty())
        return parents.first(); // the parents first will always contain the root

    // it will iterate through all the parents of the given folder, in order to
    // create any folder that has not been created.
    QStringList folder_parts = folder.split("/");
    QString aux_folder;
    RepoItem * father = parents.first();
    // there is no reason to try to find entry A/B/C if the entry A/B was not found
    bool try_to_find = true;

    for(int i = 0; i< folder_parts.size(); i++) {
        if (i ==0)
            aux_folder = folder_parts[i];
        else
            aux_folder += "/" + folder_parts[i];

        bool found = false;

        if (try_to_find) {
            // this means that the previous folders were found
            foreach(RepoItem* the_parent, parents) {
                if (the_parent->path() == aux_folder)
                {
                    found = true;
                    father = the_parent;
                    break;
                }
            }
        }
        // there is not RepoItem related to the current folder,
        // create it
        if (!found)
        {
            RepoItem * m = new RepoItem(folder_parts[i], aux_folder, father);
            father->appendChild(m);
            parents.append(m);
            father = m;
            try_to_find = false;
        }
    }
    return father;
}
void RepoTreeView::onItemDoubleClicked(const QModelIndex& index)
{
    QStandardItem *item = getRepoItem(index);
    if (!item) {
        return;
    }
    if (item->type() == REPO_ITEM_TYPE) {
        RepoItem *it = (RepoItem *)item;
        const LocalRepo& local_repo = it->localRepo();
        if (local_repo.isValid()) {
            QDesktopServices::openUrl(QUrl::fromLocalFile(local_repo.worktree));
        }
    }
}
void RepoTreeModel::checkSyncedRepo(const ServerRepo& repo)
{
    int row, n = synced_repos_category_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(synced_repos_category_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    synced_repos_category_->appendRow(item);
}
void RepoTreeModel::checkVirtualRepo(const ServerRepo& repo)
{
    if (item(kIndexOfVirtualReposCategory) != virtual_repos_category_) {
        insertRow(kIndexOfVirtualReposCategory, virtual_repos_category_);
    }

    int row, n = virtual_repos_category_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(virtual_repos_category_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    virtual_repos_category_->appendRow(item);
}
void RepoTreeModel::onFilterTextChanged(const QString& text)
{
    // Recalculate the matched repos count for each category
    QStandardItem *root = invisibleRootItem();
    int row, n;
    n = root->rowCount();
    QRegExp re = makeFilterRegExp(text);
    for (row = 0; row < n; row++) {
        RepoCategoryItem *category = (RepoCategoryItem *)root->child(row);
        int j, total, matched = 0;
        total = category->rowCount();
        for (j = 0; j < total; j++) {
            RepoItem *item = (RepoItem *)category->child(j);
            if (item->repo().name.contains(re)) {
                matched++;
            }
        }
        category->setMatchedReposCount(matched);
    }
}
bool RepoFilterProxyModel::lessThan(const QModelIndex &left,
                                    const QModelIndex &right) const
{
    RepoTreeModel *tree_model = (RepoTreeModel *)(sourceModel());
    QStandardItem *item_l = tree_model->itemFromIndex(left);
    QStandardItem *item_r = tree_model->itemFromIndex(right);

    /**
     * When we have filter: sort category by matched repos count
     * When we have no filter: sort category by category index order
     *
     */
    if (item_l->type() == REPO_CATEGORY_TYPE) {
        // repo categories
        RepoCategoryItem *cl = (RepoCategoryItem *)item_l;
        RepoCategoryItem *cr = (RepoCategoryItem *)item_r;
        if (has_filter_) {
            // printf ("%s matched: %d, %s matched: %d\n",
            //         cl->name().toUtf8().data(), cl->matchedReposCount(),
            //         cr->name().toUtf8().data(), cr->matchedReposCount());
            return cl->matchedReposCount() > cr->matchedReposCount();
        } else {
            int cat_l = cl->categoryIndex();
            int cat_r = cr->categoryIndex();
            if (cat_l == cat_r) {
                return cl->name() < cr->name();
            } else {
                return cat_l < cat_r;
            }
        }
    } else {
        // repos
        RepoItem *cl = (RepoItem *)item_l;
        RepoItem *cr = (RepoItem *)item_r;
        return cl->repo().mtime > cr->repo().mtime;
    }

    return false;
}
void RepoTreeModel::checkGroupRepo(const ServerRepo& repo)
{
    QStandardItem *root = invisibleRootItem();
    RepoCategoryItem *group = NULL;

    int row, n = root->rowCount();

    for (row = 0; row < n; row ++) {
        RepoCategoryItem *item = (RepoCategoryItem *)(root->child(row));
        if (item->groupId() == repo.group_id) {
            group = item;
            break;
        }
    }
    if (!group) {
        if (repo.group_name == "Organization") {
            group = new RepoCategoryItem(CAT_INDEX_PUBLIC_REPOS, tr("Organization"), repo.group_id);
            // Insert pub repos after "recent updated", "my libraries", "shared libraries"
            insertRow(3, group);
        } else {
            group = new RepoCategoryItem(CAT_INDEX_GROUP_REPOS, repo.group_name, repo.group_id);
            appendRow(group);
        }
    }

    // Find the repo in this group
    n = group->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(group->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // Current repo not in this group yet
    RepoItem *item = new RepoItem(repo);
    group->appendRow(item);
}
Beispiel #17
0
/** An hierarchical structure is able to define any point giving the parent, the row and the
 *  column. This method is ment to be used to the View to iterate through the model.
 *
 * @param row: the index of the children  (file/folder) under the given folder(parent)
 * @param column: The related column (repomodel defines 3 (path, status, autoupdate)
 * @param parent: The QModelIndex parent which refers to the parent folder.
 *
 * @return The QModelIndex that allows to retrieve the information of the desired child.
 */
QModelIndex RepoModel::index(int row, int column, const QModelIndex &parent) const
{
    // check if the row and column are allowed,
    // for example, it will not accept column == 3, or row = 1
    // for parent that refers to file and not to folder.
    if (!hasIndex(row, column, parent))
        return QModelIndex();
    // retrieve the pointer ot the RepoItem from the parent
    RepoItem *parentItem;
    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<RepoItem*>(parent.internalPointer());

    // given the row, we can find the childItem from the RepoItem::child method.
    RepoItem *childItem = parentItem->child(row);

    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}
void RepoTreeView::updateRepoActions()
{
    RepoItem *item = NULL;
    QItemSelection selected = selectionModel()->selection();
    QModelIndexList indexes = selected.indexes();
    if (indexes.size() != 0) {
        const QModelIndex& index = indexes.at(0);
        QStandardItem *it = ((RepoTreeModel *)model())->itemFromIndex(index);
        if (it && it->type() == REPO_ITEM_TYPE) {
            item = (RepoItem *)it;
        }
    }

    if (!item) {
        // No repo item is selected
        download_action_->setEnabled(false);
        open_local_folder_action_->setEnabled(false);
        unsync_action_->setEnabled(false);
        toggle_auto_sync_action_->setEnabled(false);
        view_on_web_action_->setEnabled(false);
        show_detail_action_->setEnabled(false);
        return;
    }

    LocalRepo r;
    seafApplet->rpcClient()->getLocalRepo(item->repo().id, &r);
    item->setLocalRepo(r);

    if (item->localRepo().isValid()) {
        const LocalRepo& local_repo = item->localRepo();
        download_action_->setEnabled(false);
        open_local_folder_action_->setData(QVariant::fromValue(local_repo));
        open_local_folder_action_->setEnabled(true);

        unsync_action_->setData(QVariant::fromValue(local_repo));
        unsync_action_->setEnabled(true);

        toggle_auto_sync_action_->setData(QVariant::fromValue(local_repo));
        toggle_auto_sync_action_->setEnabled(true);
        if (local_repo.auto_sync) {
            toggle_auto_sync_action_->setText(tr("Disable auto sync"));
            toggle_auto_sync_action_->setToolTip(tr("Disable auto sync"));
            toggle_auto_sync_action_->setIcon(QIcon(":/images/pause.png"));
        } else {
            toggle_auto_sync_action_->setText(tr("Enable auto sync"));
            toggle_auto_sync_action_->setToolTip(tr("Enable auto sync"));
            toggle_auto_sync_action_->setIcon(QIcon(":/images/play.png"));
        }

    } else {
        download_action_->setEnabled(true);
        download_action_->setData(QVariant::fromValue(item->repo()));
        open_local_folder_action_->setEnabled(false);
        unsync_action_->setEnabled(false);
        toggle_auto_sync_action_->setEnabled(false);
    }

    view_on_web_action_->setEnabled(true);
    view_on_web_action_->setData(item->repo().id);
    show_detail_action_->setEnabled(true);
    show_detail_action_->setData(QVariant::fromValue(item->repo()));
}
void RepoTreeView::updateRepoActions()
{
    RepoItem *item = NULL;
    QItemSelection selected = selectionModel()->selection();
    QModelIndexList indexes = selected.indexes();
    if (indexes.size() != 0) {
        const QModelIndex& index = indexes.at(0);
        QSortFilterProxyModel *proxy = (QSortFilterProxyModel *)model();
        RepoTreeModel *tree_model = (RepoTreeModel *)(proxy->sourceModel());
        QStandardItem *it = tree_model->itemFromIndex(proxy->mapToSource(index));
        if (it && it->type() == REPO_ITEM_TYPE) {
            item = (RepoItem *)it;
        }
    }

    if (!item) {
        // No repo item is selected
        download_action_->setEnabled(false);
        download_toolbar_action_->setEnabled(false);
        sync_now_action_->setEnabled(false);
        open_local_folder_action_->setEnabled(false);
        open_local_folder_toolbar_action_->setEnabled(false);
        unsync_action_->setEnabled(false);
        resync_action_->setEnabled(false);
        toggle_auto_sync_action_->setEnabled(false);
        view_on_web_action_->setEnabled(false);
        show_detail_action_->setEnabled(false);
        return;
    }

    LocalRepo r;
    seafApplet->rpcClient()->getLocalRepo(item->repo().id, &r);
    item->setLocalRepo(r);

    if (item->localRepo().isValid()) {
        const LocalRepo& local_repo = item->localRepo();
        download_action_->setEnabled(false);
        download_toolbar_action_->setEnabled(false);

        sync_now_action_->setEnabled(true);
        sync_now_action_->setData(QVariant::fromValue(local_repo));

        open_local_folder_action_->setData(QVariant::fromValue(local_repo));
        open_local_folder_action_->setEnabled(true);
        open_local_folder_toolbar_action_->setData(QVariant::fromValue(local_repo));
        open_local_folder_toolbar_action_->setEnabled(true);

        unsync_action_->setData(QVariant::fromValue(local_repo));
        unsync_action_->setEnabled(true);

        resync_action_->setData(QVariant::fromValue(local_repo));
        resync_action_->setEnabled(true);

        toggle_auto_sync_action_->setData(QVariant::fromValue(local_repo));
        toggle_auto_sync_action_->setEnabled(true);

        QIcon q_pause = ::getMenuIconSet(":/images/pause-gray.png");
        QIcon q_play = ::getMenuIconSet(":/images/play-gray.png");
        if (local_repo.auto_sync) {
            toggle_auto_sync_action_->setText(tr("Disable auto sync"));
            toggle_auto_sync_action_->setToolTip(tr("Disable auto sync"));
            toggle_auto_sync_action_->setIcon(q_pause);
        } else {
            toggle_auto_sync_action_->setText(tr("Enable auto sync"));
            toggle_auto_sync_action_->setToolTip(tr("Enable auto sync"));
            toggle_auto_sync_action_->setIcon(q_play);
        }

    } else {
        if (item->repoDownloadable()) {
            download_action_->setEnabled(true);
            download_toolbar_action_->setEnabled(true);
            download_action_->setData(QVariant::fromValue(item->repo()));
            download_toolbar_action_->setData(QVariant::fromValue(item->repo()));
        } else {
            download_action_->setEnabled(false);
            download_toolbar_action_->setEnabled(false);
        }

        sync_now_action_->setEnabled(false);

        open_local_folder_action_->setEnabled(false);
        open_local_folder_toolbar_action_->setEnabled(false);
        unsync_action_->setEnabled(false);
        resync_action_->setEnabled(false);
        toggle_auto_sync_action_->setEnabled(false);
    }

    view_on_web_action_->setEnabled(true);
    view_on_web_action_->setData(item->repo().id);
    show_detail_action_->setEnabled(true);
    show_detail_action_->setData(QVariant::fromValue(item->repo()));

    if (item->cloneTask().isCancelable()) {
        cancel_download_action_->setEnabled(true);
        cancel_download_action_->setData(QVariant::fromValue(item->repo()));
    } else {
        cancel_download_action_->setEnabled(false);
    }
    emit dataChanged(indexes.at(0), indexes.at(0));
}
Beispiel #20
0
/**Provide access to the data through the defined QAbstractItemModel definition.
   The index parameter defines how to access the corresponded data while the role
   define the kind of information desired from RepoModel. This method will be queried
   from QView in order to populate the view.

   From the index.internalPointer the RepoModel will have access to the path,
   which uniquely define its entry on ScriptRepository.

   The RepoModel defines 4 columns:
    - Path
    - Status
    - AutoUpdate
    - Delete

   The path, provides the name of the file. The status, give information on the ScriptRepository
   entries. Currently, an entry may be found on the following states:
     - LOCAL_ONLY: The file only exists locally.
     - REMTOE_ONLY: The file has not been downloaded.
     - REMOTE_CHANGED: A new version of the file is available.
     - LOCAL_CHANGED: The file has been changed from the original one.
     - BOTH_CHANGED: Locally and remotelly changed.
     - UPDATED: The remote and local file are identical.

   The AutoUpdate allow to flag the entries to receive the updates automatically when new files
   are available at the central repository.

   The delete column will return a string "protected" or "deletable" that will be used to know if it
   can be deleted or not. For the current version, folders are protected, and files are deletable.

   The repomodel will react to the following roles:
     - DisplayRole: to provide the main information.
     - DecorationRole: to provide icons to make easier and fancier to identify the files and folders.
     - ToolTipRole: to provide user help to interact with this class.
 */
QVariant RepoModel::data(const QModelIndex &index, int role) const
{
    using namespace Mantid::API;
    if (!index.isValid())
        return QVariant();
    RepoItem *item = static_cast<RepoItem*>(index.internalPointer());
    try {
        QString path = item->path();
        Mantid::API::ScriptInfo inf ;
        Mantid::API::SCRIPTSTATUS status;
        // return the data for the display role
        if (role == Qt::DisplayRole) {
            switch(index.column()) {
            case 0: // return the label (the path of the file/folder)
                return item->label();
                break;
            case 1: // ask for the status
                if (isDownloading(index))
                    return downloadSt();
                if (isUploading(index))
                    return uploadSt();
                status = repo_ptr->fileStatus(path.toStdString());
                return fromStatus(status);
                break;
            case 2:// autoupdate option
                status = repo_ptr->fileStatus(path.toStdString());
                if (status == REMOTE_ONLY || status == LOCAL_ONLY)
                    return QVariant();
                inf = repo_ptr->fileInfo(path.toStdString());
                return inf.auto_update?QString("true"):QString("false");
                break;
            case 3:// delete action
                inf = repo_ptr->fileInfo(path.toStdString());
                if (inf.directory)
                    return PROTECTEDENTRY;
                status = repo_ptr->fileStatus(path.toStdString());
                if (!(status == LOCAL_CHANGED || status == BOTH_UNCHANGED))
                    return PROTECTEDENTRY;
                return DELETABLEENTRY;
                break;
            }
        }

        // return the data for the DecorationRole
        if (role == Qt::DecorationRole) {
            if (index.column() == 0) {
                inf = repo_ptr->fileInfo(path.toStdString());
                if (inf.directory) {
                    status = repo_ptr->fileStatus(path.toStdString());
                    if (status == Mantid::API::REMOTE_ONLY)
                        return QIcon::fromTheme("folder-remote",QIcon(QPixmap(":/win/folder-remote")));
                    else
                        return QIcon::fromTheme("folder", QIcon(QPixmap(":/win/folder")));
                }
                else {
                    int pos = QString(path).lastIndexOf('.');
                    if (pos < 0)
                        return QIcon::fromTheme("unknown", QIcon(QPixmap(":/win/unknown")));
                    if (path.contains("readme",Qt::CaseInsensitive))
                        return QIcon::fromTheme("text-x-readme", QIcon(QPixmap(":/win/txt_file.png")));

                    QString extension = QString(path).remove(0,pos);
                    if (extension == ".cpp" || extension == ".CPP" || extension == ".c" || extension == ".C")
                        return QIcon::fromTheme("text-x-c++", QIcon(QPixmap(":/win/unknown")));
                    else if (extension == ".py" || extension == ".PY")
                        return QIcon::fromTheme("text-x-python", QIcon(QPixmap(":/win/text-x-python")));
                    else if (extension == ".ui")
                        return QIcon::fromTheme("document", QIcon(QPixmap(":/win/document")));
                    else if (extension == ".docx" || extension == ".doc" || extension == ".odf")
                        return QIcon::fromTheme("x-office-document", QIcon(QPixmap(":/win/office-document")));
                    else if (extension == ".pdf")
                        return QIcon::fromTheme("application-pdf", QIcon(QPixmap(":/win/file_pdf")));
                    else
                        return QIcon::fromTheme("unknown", QIcon(QPixmap(":/win/unknown")));
                }
            }
        }// end decorationRole

        // tool tip role
        if (role == Qt::ToolTipRole) {
            if (index.column() == 1) {
                if (isDownloading(index))
                    return "Downloading... Be patient.";
                if (isUploading(index))
                    return "Uploading... Be patient.";
                status = repo_ptr->fileStatus(path.toStdString());
                inf = repo_ptr->fileInfo(path.toStdString());
                switch(status) {

                case REMOTE_ONLY:
                    return (inf.directory)?"Click here to download this folder and all its files"
                           :"Click here to download this file";
                    break;
                case BOTH_UNCHANGED:
                    return (inf.directory)? "This folder is up-to-date" : "This file is up-to-date";
                    break;
                case LOCAL_CHANGED:
                    return "Click here to publish your changes";
                case REMOTE_CHANGED:
                case BOTH_CHANGED:
                    return (inf.directory)?
                           "There is a new version of the files inside this folder. Click here to install them.":
                           "There is a new version of this file available. Click here to install it.";
                    break;
                case LOCAL_ONLY:
                    return "Click here to share this file with the Mantid community!";

                }
            } else if (index.column() == 2) {
                return "Enable or disable this item to be downloaded automatically when new versions will be available";
            } else if (index.column() == 3) {
                if (isUploading(index))
                    return "Connection busy... Be patient.";
                inf = repo_ptr->fileInfo(path.toStdString());
                if (inf.directory)
                    return QVariant();
                status = repo_ptr->fileStatus(path.toStdString());
                if (!(status == LOCAL_CHANGED || status == BOTH_UNCHANGED))
                    return QVariant();
                return "Click here to delete this file from the Central Repository";
            }
        }// end tool tip
    } catch(Mantid::API::ScriptRepoException & ex) {
        handleExceptions(ex,"",false);
    }
    return QVariant();
}
Beispiel #21
0
bool RepoModel::isUploading(const QModelIndex & index)const {
    RepoItem *item = static_cast<RepoItem*>(index.internalPointer());
    if (item)
        return item->path() == uploading_path;
    return false;
}
Beispiel #22
0
/** The ScriptRepository allows to download and upload file and folders. And to
 * configure the AutoUpdate option for the entries. These actions will be available
 * through the setData method.
 *
 * The setData will recognize only the EditRole as a valid Role.
 * The RepoModel will recognize the following entries. The path can not be edited
 * (column 0) is not editable. the AutoUpdate flag (column 2) will accept the following
 * actions: setTrue and setFalse, to enable or disable the automatic update.
 *
 * The Status (column 1) will accept the following actions: Download and Upload.
 *
 *
 *
 */
bool RepoModel::setData(const QModelIndex & index, const QVariant & value,
                        int role) {
    if (!index.isValid())
        return false;
    if (role != Qt::EditRole)
        // only EditRole is acceptable for the role
        return false;
    if (index.column() == 0)
        // the path can not be changed
        return false;
    int count_changed = 0;
    RepoItem * item = static_cast<RepoItem*>(index.internalPointer());
    std::string path = item->path().toStdString();

    bool ret = false;
    // get the action
    QString action = value.toString();
    if (index.column() ==2) { // set auto update
        bool option;
        if (action == "setTrue")
            option = true;
        else if (action == "setFalse")
            option = false;
        else
            return false; // only setTrue and setFalse are allowed values for set auto update.
        count_changed = repo_ptr->setAutoUpdate(path, option);
        ret = true;
    }

    if (index.column() == 1) { // trigger actions: Download and Upload
        if (action == "Download") {
            if (!download_threads.isFinished()) {
                QWidget * father = qobject_cast<QWidget*>(QObject::parent());
                QMessageBox::information(father, "Wait", "Downloading... ");
                return false;
            }
            downloading_path = QString::fromStdString(path);
            download_index = index;
            emit executingThread(true);
            download_threads = QtConcurrent::run(download_thread, repo_ptr, path);
            download_watcher.setFuture(download_threads);
            ret = true;
        } else if (action == "Upload") {
            if (!upload_threads.isFinished()) {
                QWidget * father = qobject_cast<QWidget*>(QObject::parent());
                QMessageBox::information(father, "Wait", "Uploading... ");
                return false;
            }

            QWidget * father = qobject_cast<QWidget*>(QObject::parent());
            if (repo_ptr->fileInfo(path).directory) {
                QMessageBox::information(father,
                                         "Not Supported",
                                         "The current version does not support uploading recursively. Please, upload one-by-one");
                return false;
            };

            UploadForm * form = new UploadForm(QString::fromStdString(path), father);
            QSettings settings;
            settings.beginGroup("Mantid/ScriptRepository");
            QString email = settings.value("UploadEmail",QString()).toString();
            QString author = settings.value("UploadAuthor",QString()).toString();
            bool lastChk = settings.value("UploadSaveInfo",false).toBool();
            if (!email.isEmpty())
                form->setEmail(email);
            if (!author.isEmpty())
                form->setAuthor(author);
            form->lastSaveOption(lastChk);
            if (form->exec()) {
                settings.setValue("UploadEmail",form->saveInfo()?form->email():"");
                settings.setValue("UploadAuthor",form->saveInfo()?form->author():"");
                settings.setValue("UploadSaveInfo",form->saveInfo());

                qDebug() << "Uploading... "<< QString::fromStdString(path) << form->comment()
                         << form->author() << form->email() << endl;
                uploading_path = QString::fromStdString(path);
                upload_index = index;
                emit executingThread(true);
                upload_threads = QtConcurrent::run(upload_thread, repo_ptr, path, form->email(),
                                                   form->author(), form->comment());
                upload_watcher.setFuture(upload_threads);
                ret = true;
            } else {
                ret = false;
            }
            settings.endGroup();
            delete form;
        }
    }


    if (index.column() == 3) { // trigger actions: delete
        using namespace Mantid::API;
        if (action != "delete")
            return false;
        // used to show qwidgets
        QWidget * father = qobject_cast<QWidget*>(QObject::parent());

        SCRIPTSTATUS status = repo_ptr->fileStatus(path);

        /* We do not remove files directly from the central repository, but, usually,
           this option is not available from the GUI (no button), so, just return false*/
        if (!(status == LOCAL_CHANGED || status == BOTH_UNCHANGED))
            return false;

        // it requires a new connection to the uploader server
        if (!upload_threads.isFinished()) {
            QWidget * father = qobject_cast<QWidget*>(QObject::parent());
            QMessageBox::information(father, "Wait", "The connection with the server is busy now, wait a while and try again. ");
            return false;
        }
        //query the user if he wants to delete only locally or remote as well.
        DeleteQueryBox * box = new DeleteQueryBox(QString::fromStdString(path), father);

        if (box->exec() != QMessageBox::Yes) {
            // the user gave up deleting this entry, release memory
            delete box;
            box = 0;
            return false;
        }

        // get the options from the user
        QString comment(box->comment());
        {   // release memory
            delete box;
            box = 0;
        }

        // remove from central repository
        // currently, directories can not be deleted recursively
        if (repo_ptr->fileInfo(path).directory) {
            QMessageBox::information(father,
                                     "Not Supported",
                                     "The current version does not support deleting from the central repository recursively. Please, delete one-by-one");
            return false;
        };

        // check if the reason was given and it is valid
        if (comment.isEmpty()) {
            QMessageBox::information(father, "Not Allowed",
                                     "You are not allowed to delete one file without a reason");
            return false;
        }

        // we will not allow them to remove if they have no e-mail and author saved
        QSettings settings;
        settings.beginGroup("Mantid/ScriptRepository");
        QString email = settings.value("UploadEmail",QString()).toString();
        QString author = settings.value("UploadAuthor",QString()).toString();
        settings.endGroup();

        if (author.isEmpty() || email.isEmpty()) {
            QMessageBox::information(father, "You have not uploaded this file",
                                     "You are not allowed to remove files that you have not updloaded through ScriptRepository");
            return false;
        }

        // we have all we need to delete from the central repository
        // execute the delete in a separate thread, we will use the upload established way, because,
        // it will connect to the same server to delete.
        upload_index = index;
        uploading_path = QString::fromStdString(path);
        emit executingThread(true);
        upload_threads = QtConcurrent::run(delete_thread, repo_ptr, path,
                                           email, author, comment);
        upload_watcher.setFuture(upload_threads);
        ret = true;
    }// end delete action

    if (ret)
        emit dataChanged(index, this->index(count_changed,0,index));

    return ret;
}