Beispiel #1
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);
  }
}
static gpointer _dentry_ui_init(GtkBuilder *ui, gpointer uidata, FmFileInfoList *files)
{
    GObject *widget;
    GtkWidget *new_widget;
    FmFilePropertiesDEntryData *data;
    GtkTable *table;
    GtkLabel *label;
    GError *err = NULL;
    FmFileInfo *fi;
    GFile *gf;
    gchar *txt;
    gsize length;
    const gchar * const *langs;
    gboolean tmp_bool;

    /* disable permissions tab and open_with in any case */
#define HIDE_WIDGET(x) widget = gtk_builder_get_object(ui, x); \
        gtk_widget_hide(GTK_WIDGET(widget))
    /* HIDE_WIDGET("permissions_tab");
       TODO: made visibility of permissions_tab configurable */
    table = GTK_TABLE(gtk_builder_get_object(ui, "general_table"));
    HIDE_WIDGET("open_with");
    HIDE_WIDGET("open_with_label");
    gtk_table_set_row_spacing(table, 5, 0);
    /* we will do the thing only for single file! */
    if (fm_file_info_list_get_length(files) != 1)
        return NULL;
    fi = fm_file_info_list_peek_head(files);
    gf = fm_path_to_gfile(fm_file_info_get_path(fi));
    if (!g_file_load_contents(gf, NULL, &txt, &length, NULL, NULL))
    {
        g_warning("file properties dialog: cannot access desktop entry file");
        g_object_unref(gf);
        return NULL;
    }
    data = g_slice_new(FmFilePropertiesDEntryData);
    data->changed = FALSE;
    data->file = gf;
    data->kf = g_key_file_new();
    g_key_file_load_from_data(data->kf, txt, length,
                              G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                              NULL);
    g_free(txt);
    /* FIXME: handle errors, also do g_key_file_has_group() */
    /* get locale name */
    data->lang = NULL;
    langs = g_get_language_names();
    if (strcmp(langs[0], "C") != 0)
    {
        /* remove encoding from locale name */
        char *sep = strchr(langs[0], '.');
        if (sep)
            data->lang = g_strndup(langs[0], sep - langs[0]);
        else
            data->lang = g_strdup(langs[0]);
    }
    /* enable events for icon */
    widget = gtk_builder_get_object(ui, "icon_eventbox");
    data->icon = gtk_builder_get_object(ui, "icon");
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    /* disable Name event handler in the widget */
    widget = gtk_builder_get_object(ui, "name");
    g_signal_handlers_block_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, uidata);
    g_signal_connect(widget, "changed", G_CALLBACK(_dentry_name_changed), data);
    data->name = GTK_ENTRY(widget);
    data->saved_name = g_strdup(gtk_entry_get_text(data->name));
    /* FIXME: two lines below is temporary workaround on FIXME in widget */
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    gtk_editable_set_editable(GTK_EDITABLE(widget), TRUE);
    /* Name is set from "Name" by libfm already so don't touch it */
    /* support 'hidden' option */
    data->hidden = NULL;
    widget = gtk_builder_get_object(ui, "hidden");
    if (widget && GTK_IS_TOGGLE_BUTTON(widget) && fm_file_info_is_native(fi))
    {
        data->hidden = (GtkToggleButton*)widget;
        data->was_hidden = fm_file_info_is_hidden(fi);
        g_signal_connect(widget, "toggled", G_CALLBACK(_dentry_hidden_toggled), data);
        gtk_widget_set_can_focus(GTK_WIDGET(data->hidden), TRUE);
        /* set sensitive since it can be toggled for desktop entry */
        gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE);
        gtk_widget_show(GTK_WIDGET(data->hidden));
    }
#undef HIDE_WIDGET
    /* FIXME: migrate to GtkGrid */
    table = GTK_TABLE(gtk_table_new(8, 2, FALSE));
    gtk_table_set_row_spacings(table, 4);
    gtk_table_set_col_spacings(table, 12);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    /* row 0: "Exec" GtkHBox: GtkEntry+GtkButton */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>Co_mmand:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
#if GTK_CHECK_VERSION(3, 2, 0)
    /* FIXME: migrate to GtkGrid */
    widget = G_OBJECT(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6));
#else
    widget = G_OBJECT(gtk_hbox_new(FALSE, 6));
#endif
    new_widget = gtk_button_new_with_mnemonic(_("_Browse..."));
    gtk_box_pack_end(GTK_BOX(widget), new_widget, FALSE, FALSE, 0);
    g_signal_connect(new_widget, "clicked",
                     G_CALLBACK(_dentry_browse_exec_event), data);
    new_widget = gtk_entry_new();
    data->exec = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Exec", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->exec, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("Command to execute when the application icon is activated"));
    gtk_box_pack_start(GTK_BOX(widget), new_widget, TRUE, TRUE, 0);
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_exec_changed), data);
    gtk_table_attach(table, GTK_WIDGET(widget), 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 1: "Terminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Execute in terminal emulator"));
    data->terminal = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "Terminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->terminal, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_terminal_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 1, 2, GTK_FILL, 0, 18, 0);
    /* row 2: "X-KeepTerminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Keep terminal window open after command execution"));
    data->keep_open = GTK_TOGGLE_BUTTON(new_widget);
    gtk_widget_set_sensitive(new_widget, tmp_bool); /* disable if not in terminal */
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "X-KeepTerminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->keep_open, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_keepterm_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 2, 3, GTK_FILL, 0, 27, 0);
    /* row 4: "GenericName" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>D_escription:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->generic_name = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "GenericName", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->generic_name, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Generic name of the application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_genname_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 4, 5, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 3: "Path" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Working directory:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->path = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Path", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->path, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("The working directory to run the program in"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_path_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 3, 4, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 5: "Comment" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Tooltip:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->comment = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Comment", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->comment, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Tooltip to show on application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_tooltip_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 5, 6, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* TODO: handle "TryExec" field ? */
    /* row 7: "StartupNotify" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Use startup notification"));
    data->notification = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "StartupNotify", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->notification, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_notification_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 7, 8, GTK_FILL, 0, 0, 0);
    /* put the table into third tab and enable it */
    widget = gtk_builder_get_object(ui, "extra_tab_label");
    gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), _("_Desktop Entry"));
    widget = gtk_builder_get_object(ui, "extra_tab");
    gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(table));
    gtk_widget_show_all(GTK_WIDGET(widget));
    return data;
}
Beispiel #3
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);
}