Exemple #1
0
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
    GList* l = folder_infos;
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    Application* app = static_cast<Application*>(qApp);
    MainWindow* mainWindow = mainWindow_;
    Fm::FilePath path{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
    if(!mainWindow) {
        mainWindow = new MainWindow(std::move(path));
        mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());

        if(app->settings().windowMaximized()) {
            mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMaximized);
        }
    }
    else {
        mainWindow->chdir(std::move(path));
    }
    l = l->next;
    for(; l; l = l->next) {
        fi = FM_FILE_INFO(l->data);
        path = Fm::FilePath{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
        mainWindow->addTab(std::move(path));
    }
    mainWindow->show();
    mainWindow->raise();
    return true;
}
Exemple #2
0
static void on_file_info_job_finished(FmFileInfoJob* job, gpointer user_data)
{
    FmPlacesModel* model = FM_PLACES_MODEL(user_data);
    GList* l;
    GtkTreeIter it;
    FmPlaceItem* item;
    FmFileInfo* fi;

    /* g_debug("file info job finished"); */
    model->jobs = g_slist_remove(model->jobs, job);

    if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &it))
        return;

    if(fm_list_is_empty(job->file_infos))
        return;

    /* optimize for one file case */
    if(fm_list_get_length(job->file_infos) == 1)
    {
        fi = FM_FILE_INFO(fm_list_peek_head(job->file_infos));
        do {
            item = NULL;
            gtk_tree_model_get(GTK_TREE_MODEL(model), &it, FM_PLACES_MODEL_COL_INFO, &item, -1);
            if( item && item->fi && item->fi->path && fm_path_equal(item->fi->path, fi->path) )
            {
                fm_file_info_unref(item->fi);
                item->fi = fm_file_info_ref(fi);
                break;
            }
        }while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &it));
    }
    else
    {
        do {
            item = NULL;
            gtk_tree_model_get(GTK_TREE_MODEL(model), &it, FM_PLACES_MODEL_COL_INFO, &item, -1);
            if( item && item->fi && item->fi->path )
            {
                for(l = fm_list_peek_head_link(job->file_infos); l; l = l->next )
                {
                    fi = FM_FILE_INFO(l->data);
                    if(fm_path_equal(item->fi->path, fi->path))
                    {
                        fm_file_info_unref(item->fi);
                        item->fi = fm_file_info_ref(fi);
                        /* remove the file from list to speed up further loading.
                      * This won't cause problem since nobody else if using the list. */
                        fm_list_delete_link(job->file_infos, l);
                        break;
                    }
                }
            }
        }while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &it));
    }
}
// when the current selection in the folder view is changed
void TabPage::onSelChanged(int numSel) {
  QString msg;
  if(numSel > 0) {
    /* FIXME: display total size of all selected files. */
    if(numSel == 1) { /* only one file is selected */
      FmFileInfoList* files = folderView_->selectedFiles();
      FmFileInfo* fi = fm_file_info_list_peek_head(files);
      const char* size_str = fm_file_info_get_disp_size(fi);
      if(size_str) {
        msg = QString("\"%1\" (%2) %3")
                        .arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
                        .arg(QString::fromUtf8(size_str ? size_str : ""))
                        .arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
      }
      else {
        msg = QString("\"%1\" %2")
                        .arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
                        .arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
      }
      /* FIXME: should we support statusbar plugins as in the gtk+ version? */
      fm_file_info_list_unref(files);
    }
    else {
      goffset sum;
      GList* l;
      msg = tr("%1 item(s) selected", NULL, numSel).arg(numSel);
      /* don't count if too many files are selected, that isn't lightweight */
      if(numSel < 1000) {
        sum = 0;
        FmFileInfoList* files = folderView_->selectedFiles();
        for(l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
          if(fm_file_info_is_dir(FM_FILE_INFO(l->data))) {
            /* if we got a directory then we cannot tell it's size
            unless we do deep count but we cannot afford it */
            sum = -1;
            break;
          }
          sum += fm_file_info_get_size(FM_FILE_INFO(l->data));
        }
        if(sum >= 0) {
          char size_str[128];
          fm_file_size_to_str(size_str, sizeof(size_str), sum,
                              fm_config->si_unit);
	  msg += QString(" (%1)").arg(QString::fromUtf8(size_str));
        }
      /* FIXME: should we support statusbar plugins as in the gtk+ version? */
        fm_file_info_list_unref(files);
      }
      /* FIXME: can we show some more info on selection?
          that isn't lightweight if a lot of files are selected */
    }
  }
  statusText_[StatusTextSelectedFiles] = msg;
  Q_EMIT statusChanged(StatusTextSelectedFiles, msg);
}
Exemple #4
0
void View::onNewTab() {
  Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
  for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
    FmFileInfo* file = FM_FILE_INFO(l->data);
    Q_EMIT openDirRequested(fm_file_info_get_path(file), OpenInNewTab);
  }
}
Exemple #5
0
bool FileLauncher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
  for(GList* l = folder_infos; l; l = l->next) {
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    qDebug() << "  folder:" << QString::fromUtf8(fm_file_info_get_disp_name(fi));
  }
  return false;
}
Exemple #6
0
void View::onOpenInTerminal() {
  Application* app = static_cast<Application*>(qApp);
  Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
  for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
    FmFileInfo* file = FM_FILE_INFO(l->data);
    app->openFolderInTerminal(fm_file_info_get_path(file));
  }
}
void DesktopWindow::onRenameActivated() {
  if(FmFileInfoList* files = selectedFiles()) {
    for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
      FmFileInfo* info = FM_FILE_INFO(l->data);
      Fm::renameFile(info, NULL);
      fm_file_info_list_unref(files);
    }
  }
}
static void on_files_added(FmFolder* folder, GSList* files, gpointer user_data)
{
    GSList* l;
    for(l = files; l; l = l->next)
    {
        FmFileInfo* file = FM_FILE_INFO(l->data);
        FmPath* path = fm_file_info_get_path(file);
        char* path_str = fm_path_display_name(path, FALSE);
        g_printf("file found: %s\n", path_str);
    }
}
static gpointer queue_add_file(FmJob* fmjob, gpointer user_data)
{
    FmDirListJob* job = FM_DIR_LIST_JOB(fmjob);
    FmFileInfo* file = FM_FILE_INFO(user_data);
    /* this callback is called from the main thread */
    /* g_print("queue_add_file: %s\n", fm_file_info_get_disp_name(file)); */
    job->files_to_add = g_slist_prepend(job->files_to_add, fm_file_info_ref(file));
    if(job->delay_add_files_handler == 0)
        job->delay_add_files_handler = g_timeout_add_seconds_full(G_PRIORITY_LOW,
                        1, emit_found_files, g_object_ref(job), g_object_unref);
    return NULL;
}
Exemple #10
0
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
  GList* l = folder_infos;
  FmFileInfo* fi = FM_FILE_INFO(l->data);
  
//  TODO: Use services to resolve application settings
//  Application* app = Application::instance();
  MainWindow* mainWindow = mainWindow_;
  if(!mainWindow) {
    mainWindow = new MainWindow(fm_file_info_get_path(fi));
//    mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());
  }
  else
    mainWindow->chdir(fm_file_info_get_path(fi));
  l = l->next;
  for(; l; l = l->next) {
    fi = FM_FILE_INFO(l->data);
    mainWindow->addTab(fm_file_info_get_path(fi));
  }
  mainWindow->show();
  mainWindow->raise();
  return true;
}
Exemple #11
0
void View::prepareFileMenu(Fm::FileMenu* menu) {
  Application* app = static_cast<Application*>(qApp);
  menu->setConfirmDelete(app->settings().confirmDelete());
  menu->setConfirmTrash(app->settings().confirmTrash());
  menu->setUseTrash(app->settings().useTrash());

  // add some more menu items for dirs
  bool all_native = true;
  bool all_directory = true;
  FmFileInfoList* files = menu->files();
  for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    if(!fm_file_info_is_dir(fi))
      all_directory = false;
    else if(fm_file_info_is_dir(fi) && !fm_file_info_is_native(fi))
      all_native = false;
  }

  if (all_directory)
  {
    QAction* action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New T&ab"), menu);
    connect(action, &QAction::triggered, this, &View::onNewTab);
    menu->insertAction(menu->separator1(), action);

    action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New Win&dow"), menu);
    connect(action, &QAction::triggered, this, &View::onNewWindow);
    menu->insertAction(menu->separator1(), action);

    // TODO: add search
    // action = menu->addAction(_("Search"));

    if(all_native)
    {
      action = new QAction(QIcon::fromTheme("utilities-terminal"), tr("Open in Termina&l"), menu);
      connect(action, &QAction::triggered, this, &View::onOpenInTerminal);
      menu->insertAction(menu->separator1(), action);
    }
  }
  else {
    if(menu->pasteAction()) // NULL for trash
      menu->pasteAction()->setVisible(false);
    if(menu->createAction())
      menu->createAction()->setVisible(false);
  }
}
Exemple #12
0
void SidePane::initDirTree() {
  // TODO
  DirTreeModel* model = new DirTreeModel(view_);
  FmFileInfoJob* job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_NONE);
  model->setShowHidden(showHidden_);

  GList* l;
  /* query FmFileInfo for home dir and root dir, and then,
    * add them to dir tree model */
  fm_file_info_job_add(job, fm_path_get_home());
  fm_file_info_job_add(job, fm_path_get_root());
  /* FIXME: maybe it's cleaner to use run_async here? */
  fm_job_run_sync_with_mainloop(FM_JOB(job));
  for(l = fm_file_info_list_peek_head_link(job->file_infos); l; l = l->next) {
      FmFileInfo* fi = FM_FILE_INFO(l->data);
      model->addRoot(fi);
  }
  g_object_unref(job);

  static_cast<DirTreeView*>(view_)->setModel(model);
}
Exemple #13
0
gboolean on_dnd_dest_files_dropped(FmDndDest* dd, GdkDragAction action,
                               int info_type, FmFileInfoList* files, FmPlacesView* view)
{
    FmPath* dest;
    GList* l;
    gboolean ret = FALSE;

    dest = fm_dnd_dest_get_dest_path(dd);
    /* g_debug("action= %d, %d files-dropped!, info_type: %d", action, fm_list_get_length(files), info_type); */

    if(!dest && action == GDK_ACTION_LINK) /* add bookmarks */
    {
        GtkTreePath* tp = view->dest_row;
        if(tp)
        {
            const GtkTreePath* sep = fm_places_model_get_separator_path(FM_PLACES_MODEL(model));
            int idx = gtk_tree_path_get_indices(tp)[0] - gtk_tree_path_get_indices(sep)[0];

            if(view->dest_pos == GTK_TREE_VIEW_DROP_BEFORE)
                --idx;
            for( l=fm_list_peek_head_link(files); l; l=l->next, ++idx )
            {
                FmBookmarkItem* item;
                FmFileInfo* fi = FM_FILE_INFO(l->data);
                if(fm_file_info_is_dir(fi))
                    item = fm_bookmarks_insert( FM_PLACES_MODEL(model)->bookmarks, fi->path, fi->disp_name, idx);
                /* we don't need to add item to places view. Later the bookmarks will be reloaded. */
            }
        }
        ret = TRUE;
    }

    if(view->dest_row)
    {
        gtk_tree_path_free(view->dest_row);
        view->dest_row = NULL;
    }
    return ret;
}
Exemple #14
0
gboolean fm_dnd_dest_drag_data_received(FmDndDest* dd, GdkDragContext *drag_context,
             gint x, gint y, GtkSelectionData *sel_data, guint info, guint time)
{
    FmList* files = NULL;
    GtkWidget *dest_widget = dd->widget;

    if(info ==  FM_DND_DEST_TARGET_FM_LIST)
    {
        if((sel_data->length >= 0) && (sel_data->format==8))
        {
            /* get the pointer */
            memcpy(&files, sel_data->data, sel_data->length);
            if(files)
                fm_list_ref(files);
            if(files)
            {
                FmFileInfo* fi = FM_FILE_INFO(fm_list_peek_head(files));
                /* get the device of the first dragged source file */
                if(fm_path_is_native(fi->path))
                    dd->src_dev = fi->dev;
                else
                    dd->src_fs_id = fi->fs_id;
            }
        }
    }
    else if(info == FM_DND_DEST_TARGET_URI_LIST)
    {
        if((sel_data->length >= 0) && (sel_data->format==8))
        {
            gchar **uris;
            uris = gtk_selection_data_get_uris( sel_data );
            files = fm_path_list_new_from_uris((const char **)uris);
            g_free(uris);
            if(files)
            {
                GFileInfo* inf;
                FmPath* path = FM_PATH(fm_list_peek_head(files));
                GFile* gf = fm_path_to_gfile(path);
                const char* attr = fm_path_is_native(path) ? G_FILE_ATTRIBUTE_UNIX_DEVICE : G_FILE_ATTRIBUTE_ID_FILESYSTEM;
                inf = g_file_query_info(gf, attr, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
                g_object_unref(gf);

                if(fm_path_is_native(path))
                    dd->src_dev = g_file_info_get_attribute_uint32(inf, G_FILE_ATTRIBUTE_UNIX_DEVICE);
                else
                    dd->src_fs_id = g_intern_string(g_file_info_get_attribute_string(inf, G_FILE_ATTRIBUTE_ID_FILESYSTEM));
                g_object_unref(inf);
            }
        }
    }
    else if(info == FM_DND_DEST_TARGET_XDS) /* X direct save */
    {
        if( sel_data->format == 8 && sel_data->length == 1 && sel_data->data[0] == 'F')
        {
            gdk_property_change(GDK_DRAWABLE(drag_context->source_window),
                               xds_target_atom,
                               gdk_atom_intern_static_string("text/plain"), 8,
                               GDK_PROP_MODE_REPLACE, (const guchar *)"", 0);
        }
        else if(sel_data->format == 8 && sel_data->length == 1 && sel_data->data[0] == 'S')
        {
            /* XDS succeeds */
        }
        gtk_drag_finish(drag_context, TRUE, FALSE, time);
        return TRUE;
    }
    else
        return FALSE;

    /* remove previously cached source files. */
    if(G_UNLIKELY(dd->src_files))
    {
        fm_list_unref(dd->src_files);
        dd->src_files = NULL;
    }
    dd->src_files = files;
    dd->waiting_data = FALSE;
    dd->info_type = info;
    return TRUE;
}
Exemple #15
0
void FilePropsDialog::initPermissionsPage() {
  // ownership handling
  // get owner/group and mode of the first file in the list
  uid = fm_file_info_get_uid(fileInfo);
  gid = fm_file_info_get_gid(fileInfo);
  mode_t mode = fm_file_info_get_mode(fileInfo);
  ownerPerm = (mode & (S_IRUSR|S_IWUSR|S_IXUSR));
  groupPerm = (mode & (S_IRGRP|S_IWGRP|S_IXGRP));
  otherPerm = (mode & (S_IROTH|S_IWOTH|S_IXOTH));
  execPerm = (mode & (S_IXUSR|S_IXGRP|S_IXOTH));
  allNative = fm_file_info_is_native(fileInfo);
  hasDir = S_ISDIR(mode);

  // check if all selected files belongs to the same owner/group or have the same mode
  // at the same time, check if all files are on native unix filesystems
  GList* l;
  for(l = fm_file_info_list_peek_head_link(fileInfos_)->next; l; l = l->next) {
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    if(allNative && !fm_file_info_is_native(fi))
      allNative = false; // not all of the files are native

    mode_t fi_mode = fm_file_info_get_mode(fi);
    if(S_ISDIR(fi_mode))
      hasDir = true; // the files list contains dir(s)

    if(uid != DIFFERENT_UIDS && uid != fm_file_info_get_uid(fi))
      uid = DIFFERENT_UIDS; // not all files have the same owner
    if(gid != DIFFERENT_GIDS && gid != fm_file_info_get_gid(fi))
      gid = DIFFERENT_GIDS; // not all files have the same owner group

    if(ownerPerm != DIFFERENT_PERMS && ownerPerm != (fi_mode & (S_IRUSR|S_IWUSR|S_IXUSR)))
      ownerPerm = DIFFERENT_PERMS; // not all files have the same permission for owner
    if(groupPerm != DIFFERENT_PERMS && groupPerm != (fi_mode & (S_IRGRP|S_IWGRP|S_IXGRP)))
      groupPerm = DIFFERENT_PERMS; // not all files have the same permission for grop
    if(otherPerm != DIFFERENT_PERMS && otherPerm != (fi_mode & (S_IROTH|S_IWOTH|S_IXOTH)))
      otherPerm = DIFFERENT_PERMS; // not all files have the same permission for other
    if(execPerm != DIFFERENT_PERMS && execPerm != (fi_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
      execPerm = DIFFERENT_PERMS; // not all files have the same executable permission
  }

  // init owner/group
  initOwner();

  // if all files are of the same type, and some of them are dirs => all of the items are dirs
  // rwx values have different meanings for dirs
  // Let's make it clear for the users
  // init combo boxes for file permissions here
  QStringList comboItems;
  comboItems.append("---"); // no change
  if(singleType && hasDir) { // all files are dirs
    comboItems.append(tr("View folder content"));
    comboItems.append(tr("View and modify folder content"));
    ui->executable->hide();
  }
  else { //not all of the files are dirs
    comboItems.append(tr("Read"));
    comboItems.append(tr("Read and write"));
  }
  comboItems.append(tr("Forbidden"));
  QStringListModel* comboModel = new QStringListModel(comboItems, this);
  ui->ownerPerm->setModel(comboModel);
  ui->groupPerm->setModel(comboModel);
  ui->otherPerm->setModel(comboModel);

  // owner
  ownerPermSel = ACCESS_NO_CHANGE;
  if(ownerPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
    if(ownerPerm & S_IRUSR) { // can read
      if(ownerPerm & S_IWUSR) // can write
        ownerPermSel = ACCESS_READ_WRITE;
      else
        ownerPermSel = ACCESS_READ_ONLY;
    }
    else {
      if((ownerPerm & S_IWUSR) == 0) // cannot read or write
        ownerPermSel = ACCESS_FORBID;
    }
  }
  ui->ownerPerm->setCurrentIndex(ownerPermSel);

  // owner and group
  groupPermSel = ACCESS_NO_CHANGE;
  if(groupPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
    if(groupPerm & S_IRGRP) { // can read
      if(groupPerm & S_IWGRP) // can write
        groupPermSel = ACCESS_READ_WRITE;
      else
        groupPermSel = ACCESS_READ_ONLY;
    }
    else {
      if((groupPerm & S_IWGRP) == 0) // cannot read or write
        groupPermSel = ACCESS_FORBID;
    }
  }
  ui->groupPerm->setCurrentIndex(groupPermSel);

  // other
  otherPermSel = ACCESS_NO_CHANGE;
  if(otherPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
    if(otherPerm & S_IROTH) { // can read
      if(otherPerm & S_IWOTH) // can write
        otherPermSel = ACCESS_READ_WRITE;
      else
        otherPermSel = ACCESS_READ_ONLY;
    }
    else {
      if((otherPerm & S_IWOTH) == 0) // cannot read or write
        otherPermSel = ACCESS_FORBID;
    }

  }
  ui->otherPerm->setCurrentIndex(otherPermSel);

  // set the checkbox to partially checked state
  // when owner, group, and other have different executable flags set.
  // some of them have exec, and others do not have.
  execCheckState = Qt::PartiallyChecked;
  if(execPerm != DIFFERENT_PERMS) { // if all files have the same executable permission
    // check if the files are all executable
    if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == (S_IXUSR|S_IXGRP|S_IXOTH)) {
      // owner, group, and other all have exec permission.
      ui->executable->setTristate(false);
      execCheckState = Qt::Checked;
    }
    else if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
      // owner, group, and other all have no exec permission
      ui->executable->setTristate(false);
      execCheckState = Qt::Unchecked;
    }
  }
  ui->executable->setCheckState(execCheckState);
}