Пример #1
0
static void on_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmMainWin* win)
{
	/* popup previous message if there is any */
	gtk_statusbar_pop(GTK_STATUSBAR(win->statusbar), win->statusbar_ctx2);
    if(files)
    {
        char* msg;
        /* FIXME: display total size of all selected files. */
        if(fm_list_get_length(files) == 1) /* only one file is selected */
        {
            FmFileInfo* fi = fm_list_peek_head(files);
            const char* size_str = fm_file_info_get_disp_size(fi);
            if(size_str)
            {
                msg = g_strdup_printf("\"%s\" (%s) %s",
                            fm_file_info_get_disp_name(fi),
                            size_str ? size_str : "",
                            fm_file_info_get_desc(fi));
            }
            else
            {
                msg = g_strdup_printf("\"%s\" %s",
                            fm_file_info_get_disp_name(fi),
                            fm_file_info_get_desc(fi));
            }
        }
        else
            msg = g_strdup_printf("%d items selected", fm_list_get_length(files));
        gtk_statusbar_push(GTK_STATUSBAR(win->statusbar), win->statusbar_ctx2, msg);
        g_free(msg);
    }
}
Пример #2
0
// 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);
}
Пример #3
0
static void on_folder_view_sel_changed(FmFolderView* fv, gint n_sel, FmTabPage* page)
{
    char* msg = page->status_text[FM_STATUS_TEXT_SELECTED_FILES];
    g_free(msg);

    if(n_sel > 0)
    {
        /* FIXME: display total size of all selected files. */
        if(n_sel == 1) /* only one file is selected */
        {
            FmFileInfoList* files = fm_folder_view_dup_selected_files(fv);
            FmFileInfo* fi = fm_file_info_list_peek_head(files);
            const char* size_str = fm_file_info_get_disp_size(fi);
            if(size_str)
            {
                msg = g_strdup_printf("\"%s\" (%s) %s",
                            fm_file_info_get_disp_name(fi),
                            size_str ? size_str : "",
                            fm_file_info_get_desc(fi));
            }
            else
            {
                msg = g_strdup_printf("\"%s\" %s",
                            fm_file_info_get_disp_name(fi),
                            fm_file_info_get_desc(fi));
            }
            fm_file_info_list_unref(files);
        }
        else
        {
            msg = g_strdup_printf(ngettext("%d item selected", "%d items selected", n_sel), n_sel);
        }
    }
    else
        msg = NULL;
    page->status_text[FM_STATUS_TEXT_SELECTED_FILES] = msg;
    g_signal_emit(page, signals[STATUS], 0,
                  (guint)FM_STATUS_TEXT_SELECTED_FILES, msg);
}
Пример #4
0
static gint on_ask_rename (FmFileOpsJob *job, FmFileInfo *src, FmFileInfo *dest, char **new_name, FmProgressDisplay *data)
{
    int res;
    GtkBuilder *builder = gtk_builder_new ();
    GtkWidget *dlg, *src_icon, *dest_icon, *src_fi, *dest_fi, *filename, *apply_all;
    char *tmp;
    const char *disp_size;

    // return default operation if the user has set it
    if (data->default_opt)
        return data->default_opt;

    if (data->timer)
        g_timer_stop (data->timer);

    gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
    ensure_dlg (data);

    gtk_builder_add_from_string  (builder, RENAME_DLG, -1, NULL);
    dlg =       (GtkWidget*)gtk_builder_get_object (builder, "dlg");
    src_icon =  (GtkWidget*)gtk_builder_get_object (builder, "src_icon");
    src_fi =    (GtkWidget*)gtk_builder_get_object (builder, "src_fi");
    dest_icon = (GtkWidget*)gtk_builder_get_object (builder, "dest_icon");
    dest_fi =   (GtkWidget*)gtk_builder_get_object (builder, "dest_fi");
    filename =  (GtkWidget*)gtk_builder_get_object (builder, "filename");
    apply_all = (GtkWidget*)gtk_builder_get_object (builder, "apply_all");
    
    gtk_window_set_transient_for (GTK_WINDOW (dlg), (GtkWindow*) data->dlg);

    gtk_image_set_from_gicon (GTK_IMAGE (src_icon), fm_file_info_get_gicon (src), GTK_ICON_SIZE_DIALOG);
    disp_size = fm_file_info_get_disp_size (src);
    if (disp_size)
    {
        tmp = g_strdup_printf (_("Type: %s\nSize: %s\nModified: %s"),
                              fm_file_info_get_desc (src),
                              disp_size,
                              fm_file_info_get_disp_mtime (src));
    }
    else
    {
        tmp = g_strdup_printf (_("Type: %s\nModified: %s"),
                              fm_file_info_get_desc (src),
                              fm_file_info_get_disp_mtime (src));
    }

    gtk_label_set_text (GTK_LABEL (src_fi), tmp);
    g_free (tmp);

    gtk_image_set_from_gicon (GTK_IMAGE (dest_icon), fm_file_info_get_gicon (src), GTK_ICON_SIZE_DIALOG);
    disp_size = fm_file_info_get_disp_size (dest);
    if (disp_size)
    {
        tmp = g_strdup_printf (_("Type: %s\nSize: %s\nModified: %s"),
                              fm_file_info_get_desc (dest),
                              fm_file_info_get_disp_size (dest),
                              fm_file_info_get_disp_mtime (dest));
    }
    else
    {
        tmp = g_strdup_printf (_("Type: %s\nModified: %s"),
                              fm_file_info_get_desc (dest),
                              fm_file_info_get_disp_mtime (dest));
    }

    gtk_label_set_text (GTK_LABEL (dest_fi), tmp);
    g_free (tmp);

    tmp = g_filename_display_name (dest->path->name);
    gtk_entry_set_text (GTK_ENTRY (filename), tmp);
    g_free (tmp);
    
    g_object_set_data (G_OBJECT (filename), "old_name", dest->disp_name);
    g_signal_connect (filename, "changed", (GCallback) on_filename_changed, gtk_builder_get_object (builder, "rename"));

    g_object_unref (builder);

    res = gtk_dialog_run (GTK_DIALOG (dlg));
    switch (res)
    {
        case RESPONSE_RENAME:
            *new_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (filename)));
            res = FM_FILE_OP_RENAME;
        break;
        
        case RESPONSE_OVERWRITE:
            res = FM_FILE_OP_OVERWRITE;
        break;
        
        case RESPONSE_SKIP:
            res = FM_FILE_OP_SKIP;
        break;
        
        default:
            res = FM_FILE_OP_CANCEL;
    }

    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (apply_all)))
    {
        if (res == RESPONSE_OVERWRITE || res == FM_FILE_OP_SKIP)
            data->default_opt = res;
    }

    gtk_widget_destroy (dlg);

    if (data->timer)
        g_timer_continue (data->timer);

    return res;
}
Пример #5
0
static gint on_ask_rename(FmFileOpsJob* job, FmFileInfo* src, FmFileInfo* dest, char** new_name, FmProgressDisplay* data)
{
    int res;
    GtkBuilder* builder;
    GtkDialog *dlg;
    GtkImage *src_icon, *dest_icon;
    GtkLabel *src_fi, *dest_fi;
    GtkEntry *filename;
    GtkToggleButton *apply_all;
    char* tmp;
    const char* disp_size;
    FmPath* path;
    FmIcon* icon;

    /* return default operation if the user has set it */
    if(data->default_opt)
        return data->default_opt;

    builder = gtk_builder_new();
    path = fm_file_info_get_path(dest);
    icon = fm_file_info_get_icon(src);

    if(data->timer)
        g_timer_stop(data->timer);

    gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
    ensure_dlg(data);

    gtk_builder_add_from_file(builder, PACKAGE_UI_DIR "/ask-rename.ui", NULL);
    dlg = GTK_DIALOG(gtk_builder_get_object(builder, "dlg"));
    src_icon = GTK_IMAGE(gtk_builder_get_object(builder, "src_icon"));
    src_fi = GTK_LABEL(gtk_builder_get_object(builder, "src_fi"));
    dest_icon = GTK_IMAGE(gtk_builder_get_object(builder, "dest_icon"));
    dest_fi = GTK_LABEL(gtk_builder_get_object(builder, "dest_fi"));
    filename = GTK_ENTRY(gtk_builder_get_object(builder, "filename"));
    apply_all = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "apply_all"));
    gtk_window_set_transient_for(GTK_WINDOW(dlg), GTK_WINDOW(data->dlg));

    gtk_image_set_from_gicon(src_icon, icon->gicon, GTK_ICON_SIZE_DIALOG);
    disp_size = fm_file_info_get_disp_size(src);
    if(disp_size)
    {
        tmp = g_strdup_printf(_("Type: %s\nSize: %s\nModified: %s"),
                              fm_file_info_get_desc(src),
                              disp_size,
                              fm_file_info_get_disp_mtime(src));
    }
    else
    {
        tmp = g_strdup_printf(_("Type: %s\nModified: %s"),
                              fm_file_info_get_desc(src),
                              fm_file_info_get_disp_mtime(src));
    }

    gtk_label_set_text(src_fi, tmp);
    g_free(tmp);

    gtk_image_set_from_gicon(dest_icon, icon->gicon, GTK_ICON_SIZE_DIALOG);
    disp_size = fm_file_info_get_disp_size(dest);
    if(disp_size)
    {
        tmp = g_strdup_printf(_("Type: %s\nSize: %s\nModified: %s"),
                              fm_file_info_get_desc(dest),
                              fm_file_info_get_disp_size(dest),
                              fm_file_info_get_disp_mtime(dest));
    }
    else
    {
        tmp = g_strdup_printf(_("Type: %s\nModified: %s"),
                              fm_file_info_get_desc(dest),
                              fm_file_info_get_disp_mtime(dest));
    }

    gtk_label_set_text(dest_fi, tmp);
    g_free(tmp);

    tmp = g_filename_display_name(fm_path_get_basename(path));
    gtk_entry_set_text(filename, tmp);
    g_free(tmp);
    tmp = (char*)fm_file_info_get_disp_name(dest); /* FIXME: cast const to char */
    g_object_set_data(G_OBJECT(filename), "old_name", tmp);
    g_signal_connect(filename, "changed", G_CALLBACK(on_filename_changed), gtk_builder_get_object(builder, "rename"));

    g_object_unref(builder);

    res = gtk_dialog_run(dlg);
    switch(res)
    {
    case RESPONSE_RENAME:
        *new_name = g_strdup(gtk_entry_get_text(filename));
        res = FM_FILE_OP_RENAME;
        break;
    case RESPONSE_OVERWRITE:
        res = FM_FILE_OP_OVERWRITE;
        break;
    case RESPONSE_SKIP:
        res = FM_FILE_OP_SKIP;
        break;
    default:
        res = FM_FILE_OP_CANCEL;
    }

    if(gtk_toggle_button_get_active(apply_all))
    {
        if(res == RESPONSE_OVERWRITE || res == FM_FILE_OP_SKIP)
            data->default_opt = res;
    }

    gtk_widget_destroy(GTK_WIDGET(dlg));

    if(data->timer)
        g_timer_continue(data->timer);

    return res;
}
Пример #6
0
static void on_folder_view_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmTabPage* page)
{
    char* msg = page->status_text[FM_STATUS_TEXT_SELECTED_FILES];
    g_free(msg);
    msg = NULL;

    // use SI metric by default
    static gboolean use_si_prefix = TRUE ;

    unsigned items_num = 0;

    if (files)
        items_num = fm_list_get_length(files) ;

    if (items_num > 1) // multiple items are selected
    {
        goffset items_totalsize = 0 ;

        // whether selected items contain dir
        gboolean items_contain_dir  = FALSE ;

        GList* l;
        for (l=fm_list_peek_head_link(files);l;l=l->next)
        {
            FmFileInfo* fi = (FmFileInfo*)l->data;

            // ignore dir when calculating total size. because that
            // may take a long long time, not suitable for updating
            // statusbar in real time.
            if (fm_file_info_is_dir(fi) )
            {
                items_contain_dir = TRUE;
            }
            else
            {
                // Non-dir items are regard as files
                // Should extra logic be added for different kinds of files?
                // hardlink, symlink, pipe, socket ?
                items_totalsize += fm_file_info_get_size(fi) ;
            }
        }

        // when the selected items contain dir, do not show size info on the
        // statusbar, because the calculated total size counts for files only
        // and showing it would be misleading to the user.
        if (items_contain_dir)
        {
            msg = g_strdup_printf("%d items selected", items_num);
        }
        else
        {
            char items_totalsize_str[ 64 ];
            fm_file_size_to_str( items_totalsize_str, items_totalsize, use_si_prefix );

            msg = g_strdup_printf("%d items selected, total size: %s", \
                                  items_num, items_totalsize_str);
        }

    }
    else if (items_num == 1)
    {
        FmFileInfo* fi = fm_list_peek_head(files);
        const char* size_str = fm_file_info_get_disp_size(fi);
        gboolean is_link = fm_file_info_is_symlink(fi);
        if (is_link && size_str)
        {
            msg = g_strdup_printf("\"%s\" link to \"%s\" (%s)",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_target(fi),
                                  size_str);
        }
        else if (is_link)
        {
            msg = g_strdup_printf("\"%s\" link to \"%s\"",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_target(fi));
        }
        else if (size_str)
        {
            msg = g_strdup_printf("\"%s\" (%s) %s",
                                  fm_file_info_get_disp_name(fi),
                                  size_str,
                                  fm_file_info_get_desc(fi));
        }
        else
        {
            msg = g_strdup_printf("\"%s\" %s",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_desc(fi));
        }
    }

    page->status_text[FM_STATUS_TEXT_SELECTED_FILES] = msg;
    g_signal_emit(page, signals[STATUS], 0,
                  (guint)FM_STATUS_TEXT_SELECTED_FILES, msg);
}
Пример #7
0
RenameDialog::RenameDialog(FmFileInfo* src, FmFileInfo* dest, QWidget* parent, Qt::WindowFlags f):
  QDialog(parent, f),
  action_(ActionIgnore),
  applyToAll_(false) {

  ui = new Ui::RenameDialog();
  ui->setupUi(this);

  FmPath* path = fm_file_info_get_path(dest);
  FmIcon* srcIcon = fm_file_info_get_icon(src);
  FmIcon* destIcon = fm_file_info_get_icon(dest);

  // show info for the source file
  QIcon icon = IconTheme::icon(srcIcon);
  QSize iconSize(fm_config->big_icon_size, fm_config->big_icon_size);
  QPixmap pixmap = icon.pixmap(iconSize);
  ui->srcIcon->setPixmap(pixmap);

  QString infoStr;
  const char* disp_size = fm_file_info_get_disp_size(src);
  if(disp_size) {
    infoStr = QString(tr("Type: %1\nSize: %2\nModified: %3"))
                .arg(QString::fromUtf8(fm_file_info_get_desc(src)))
                .arg(QString::fromUtf8(disp_size))
                .arg(QString::fromUtf8(fm_file_info_get_disp_mtime(src)));
  }
  else {
    infoStr = QString(tr("Type: %1\nModified: %2"))
                .arg(QString::fromUtf8(fm_file_info_get_desc(src)))
                .arg(QString::fromUtf8(fm_file_info_get_disp_mtime(src)));
  }
  ui->srcInfo->setText(infoStr);

  // show info for the dest file
  icon = IconTheme::icon(destIcon);
  pixmap = icon.pixmap(iconSize);
  ui->destIcon->setPixmap(pixmap);

  disp_size = fm_file_info_get_disp_size(dest);
  if(disp_size) {
    infoStr = QString(tr("Type: %1\nSize: %2\nModified: %3"))
                .arg(QString::fromUtf8(fm_file_info_get_desc(dest)))
                .arg(QString::fromUtf8(disp_size))
                .arg(QString::fromUtf8(fm_file_info_get_disp_mtime(dest)));
  }
  else {
    infoStr = QString(tr("Type: %1\nModified: %3"))
                .arg(QString::fromUtf8(fm_file_info_get_desc(src)))
                .arg(QString::fromUtf8(fm_file_info_get_disp_mtime(src)));
  }
  ui->destInfo->setText(infoStr);

  char* basename = fm_path_display_basename(path);
  ui->fileName->setText(QString::fromUtf8(basename));
  oldName_ = basename;
  g_free(basename);
  connect(ui->fileName, &QLineEdit::textChanged, this, &RenameDialog::onFileNameChanged);

  // add "Rename" button
  QAbstractButton* button = ui->buttonBox->button(QDialogButtonBox::Ok);
  button->setText(tr("&Overwrite"));
  // FIXME: there seems to be no way to place the Rename button next to the overwrite one.
  renameButton_ = ui->buttonBox->addButton(tr("&Rename"), QDialogButtonBox::ActionRole);
  connect(renameButton_, &QPushButton::clicked, this, &RenameDialog::onRenameClicked);
  renameButton_->setEnabled(false); // disabled by default

  button = ui->buttonBox->button(QDialogButtonBox::Ignore);
  connect(button, &QPushButton::clicked, this, &RenameDialog::onIgnoreClicked);
}
Пример #8
0
void fm_folder_model_get_value(GtkTreeModel *tree_model,
                               GtkTreeIter *iter,
                               gint column,
                               GValue *value)
{
    GSequenceIter* item_it;
    FmFolderModel* model = FM_FOLDER_MODEL(tree_model);

    g_return_if_fail(iter != NULL);
    g_return_if_fail( column < G_N_ELEMENTS(column_types) );

    g_value_init(value, column_types[column]);

    item_it = (GSequenceIter*)iter->user_data;
    g_return_if_fail(item_it != NULL);

    FmFolderItem* item = (FmFolderItem*)g_sequence_get(item_it);
    FmFileInfo* info = item->inf;

    switch( column )
    {
    case COL_FILE_GICON:
        g_value_set_object(value, info->icon->gicon);
        break;
    case COL_FILE_ICON:
    {
        if( G_UNLIKELY(!item->icon) )
        {
            if( !info->icon )
                return;
            item->icon = fm_icon_get_pixbuf(info->icon, model->icon_size);
        }

        /* if we want to show a thumbnail */
        /* if we're on local filesystem or thumbnailing for remote files is allowed */
        if(fm_config->show_thumbnail && (fm_path_is_local(item->inf->path) || !fm_config->thumbnail_local))
        {
            if(!item->is_thumbnail && !item->thumbnail_failed && !item->thumbnail_loading)
            {
                if(fm_file_info_can_thumbnail(item->inf))
                {
                    if(item->inf->size > 0 && (fm_config->thumbnail_max == 0 || item->inf->size <= (fm_config->thumbnail_max << 10)))
                    {
                        GdkPixbuf * pix = fm_thumbnail_try_read_from_cache(item->inf, model->icon_size);
                        if (pix)
                        {
                           if (item->icon)
                               g_object_unref(item->icon);
                           item->icon = pix;
                           item->is_thumbnail = TRUE;
                        }
                        else
                        {
                            FmThumbnailRequest* req = fm_thumbnail_request2(item->inf, model->icon_size, on_thumbnail_loaded, model, item->iter_age, item);
                            model->thumbnail_requests = g_list_prepend(model->thumbnail_requests, req);
                            item->thumbnail_loading = TRUE;
                        }
                    }
                }
                else
                {
                    item->thumbnail_failed = TRUE;
                }
            }
        }

        g_value_set_object(value, item->icon);
        
        break;
    }
    case COL_FILE_NAME:
        g_value_set_string(value, info->disp_name);
        break;
    case COL_FILE_NAME_HINT_SIZE:
    case COL_FILE_NAME_HINT_MTIME:
    case COL_FILE_NAME_HINT_DESC:
    {
        //g_value_set_string(value, info->disp_name);
        if (!item->hinted_disp_name || item->hint_column != column)
        {
            item->hint_column != column;
            if (item->hinted_disp_name)
                g_free(item->hinted_disp_name);

            gchar * s = NULL;
            if (fm_file_info_is_symlink(info))
                s = fm_file_info_get_target(info);
            if (!s)
            {
                switch (column)
                {
                    case COL_FILE_NAME_HINT_SIZE:
                        s = fm_file_info_get_disp_size(info);
                        break;
                    case COL_FILE_NAME_HINT_MTIME:
                        s = fm_file_info_get_disp_mtime(info);
                        break;
                    case COL_FILE_NAME_HINT_DESC:
                        s = fm_file_info_get_desc(info);
                        break;
                }
            }
            if (!s)
                s = fm_file_info_get_desc(info);
            if (!s)
                s = "";
            item->hinted_disp_name = g_markup_printf_escaped("%s<span size='small'>\n<i>%s</i></span>", info->disp_name, s);
        }
        g_value_set_string(value, item->hinted_disp_name);
        break;
    }
    case COL_FILE_SIZE:
        g_value_set_string( value, fm_file_info_get_disp_size(info) );
        break;
    case COL_FILE_DESC:
        g_value_set_string( value, fm_file_info_get_desc(info) );
        break;
    case COL_FILE_PERM:
//        g_value_set_string( value, fm_file_info_get_disp_perm(info) );
        break;
    case COL_FILE_OWNER:
//        g_value_set_string( value, fm_file_info_get_disp_owner(info) );
        break;
    case COL_FILE_MTIME:
        g_value_set_string( value, fm_file_info_get_disp_mtime(info) );
        break;
    case COL_FILE_INFO:
        g_value_set_pointer(value, info);
        break;
    }
}
Пример #9
0
static gint on_ask_rename(FmFileOpsJob* job, FmFileInfo* src, FmFileInfo* dest, char** new_name, FmProgressDisplay* data)
{
    int res;
    GtkBuilder* builder = gtk_builder_new();
    GtkWidget *dlg, *src_icon, *dest_icon, *src_fi, *dest_fi, *filename, *apply_all;
    char* tmp;
    gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
    ensure_dlg(data);

    gtk_builder_add_from_file(builder, PACKAGE_UI_DIR "/ask-rename.ui", NULL);
    dlg = (GtkWidget*)gtk_builder_get_object(builder, "dlg");
    src_icon = (GtkWidget*)gtk_builder_get_object(builder, "src_icon");
    src_fi = (GtkWidget*)gtk_builder_get_object(builder, "src_fi");
    dest_icon = (GtkWidget*)gtk_builder_get_object(builder, "dest_icon");
    dest_fi = (GtkWidget*)gtk_builder_get_object(builder, "dest_fi");
    filename = (GtkWidget*)gtk_builder_get_object(builder, "filename");
    apply_all = (GtkWidget*)gtk_builder_get_object(builder, "apply_all");
    gtk_window_set_transient_for(GTK_WINDOW(dlg), data->dlg);

    gtk_image_set_from_gicon(GTK_IMAGE(src_icon), src->icon->gicon, GTK_ICON_SIZE_DIALOG);
    tmp = g_strdup_printf("Type: %s\nSize: %s\nModified: %s",
                          fm_file_info_get_desc(src),
                          fm_file_info_get_disp_size(src),
                          fm_file_info_get_disp_mtime(src));
    gtk_label_set_text(GTK_LABEL(src_fi), tmp);
    g_free(tmp);

    gtk_image_set_from_gicon(GTK_IMAGE(dest_icon), src->icon->gicon, GTK_ICON_SIZE_DIALOG);
    tmp = g_strdup_printf("Type: %s\nSize: %s\nModified: %s",
                          fm_file_info_get_desc(dest),
                          fm_file_info_get_disp_size(dest),
                          fm_file_info_get_disp_mtime(dest));
    gtk_label_set_text(GTK_LABEL(dest_fi), tmp);
    g_free(tmp);

    gtk_entry_set_text(GTK_ENTRY(filename), dest->disp_name);
    g_object_set_data(G_OBJECT(filename), "old_name", dest->disp_name);
    g_signal_connect(filename, "changed", on_filename_changed, gtk_builder_get_object(builder, "rename"));

    g_object_unref(builder);

    res = gtk_dialog_run(GTK_DIALOG(dlg));
    switch(res)
    {
    case RESPONSE_RENAME:
        *new_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filename)));
        res = FM_FILE_OP_RENAME;
        break;
    case RESPONSE_OVERWRITE:
        res = FM_FILE_OP_OVERWRITE;
        break;
    case RESPONSE_SKIP:
        res = FM_FILE_OP_SKIP;
        break;
    default:
        res = FM_FILE_OP_CANCEL;
    }

    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(apply_all)))
    {
        /* FIXME: set default action */
    }

    gtk_widget_destroy(dlg);

    return res;
}