コード例 #1
0
NS_IMETHODIMP
ValidityState::GetCustomError(bool* aCustomError)
{
  *aCustomError = CustomError();
  return NS_OK;
}
コード例 #2
0
ファイル: plugin.cpp プロジェクト: FarManagerLegacy/farplug
intptr_t get_files(HANDLE hPlugin, struct PluginPanelItem *PanelItem, size_t ItemsNumber, int Move, UnicodeString& DestPath, OPERATION_MODES OpMode) {
  if ((ItemsNumber == 0) || (wcscmp(PanelItem[0].FileName, L"..") == 0)) return 1;
  PluginInstance* plugin = (PluginInstance*) hPlugin;
  bool show_dialog = (OpMode & (OPM_SILENT | OPM_FIND | OPM_VIEW | OPM_EDIT | OPM_QUICKVIEW)) == 0;
  bool show_error = (OpMode & (OPM_FIND | OPM_QUICKVIEW)) == 0;
  try {
    CopyFilesOptions options;
    options.show_dialog = show_dialog;
    options.show_error = show_error;
    options.dst_dir = DestPath;
    options.move_files = Move != 0;
    options.copy_shared = get_app_option(FSSF_SYSTEM, c_copy_opened_files_option, true);
    options.use_file_filters = false;
    options.use_tmp_files = (OpMode & (OPM_FIND | OPM_VIEW | OPM_QUICKVIEW)) != 0;
    if (show_dialog) {
      options.ignore_errors = g_plugin_options.ignore_errors;
      options.overwrite = g_plugin_options.overwrite;
      options.show_stats = g_plugin_options.show_stats;
      if (!show_copy_files_dlg(options, false)) BREAK;
      if (g_plugin_options.save_def_values) {
        g_plugin_options.ignore_errors = options.ignore_errors;
        g_plugin_options.overwrite = options.overwrite;
        g_plugin_options.show_stats = options.show_stats;
        save_def_option_values(g_plugin_options);
      }
      DestPath = options.dst_dir;
    }
    else {
      options.ignore_errors = false;
      options.overwrite = ooOverwrite;
      options.show_stats = ssoNever;
    }
    CopyFilesStats stats;
    Log log;
    {
      UiLink ui((OpMode & OPM_SILENT) != 0);
      if (ui.update_needed()) {
        draw_progress_msg(far_get_msg(MSG_PROGRESS_PREPARE));
      }

      // source directory
      UnicodeString src_dir_path = plugin->current_dir;

      // distination directory and file name (if renaming)
      UnicodeString dst_dir_path, dst_new_name;
      FilePath dst_fp(options.dst_dir);
      bool dst_is_remote = !dst_fp.is_absolute || (dst_fp.root.size() == 0);
      if (dst_is_remote) {
        // ensure that file name case is correct in source and destinations paths
        // it will be used later in comparison
        FilePath src_dir_fp(src_dir_path);
        find_real_file_path(src_dir_fp, plugin->session);
        src_dir_path = src_dir_fp.get_full_path();
        dst_fp = FilePath(plugin->current_dir).combine(dst_fp);
        find_real_file_path(dst_fp, plugin->session);
      }
      if ((dst_is_remote && dir_exists(dst_fp.get_full_path(), plugin->session)) || (!dst_is_remote && dir_exists(dst_fp.get_full_path()))) {
        dst_dir_path = dst_fp.get_full_path();
      }
      else {
        if (ItemsNumber != 1) {
          dst_dir_path = dst_fp.get_full_path();
        }
        else {
          dst_dir_path = dst_fp.get_dir_path();
          dst_new_name = dst_fp.get_file_name();
        }
      }

      UnicodeString src_file_name, dst_file_name; // store source / destination file names
      UnicodeString src_path, dst_path; // store source / destination file paths

      // list of selected files
      FileList panel_file_list;
      panel_items_to_file_list(PanelItem, ItemsNumber, panel_file_list);

      // verify that no file is copied into self
      if (dst_is_remote) {
        for (unsigned i = 0; i < ItemsNumber; i++) {
          src_file_name = panel_file_list[i].file_name;
          COMPOSE_PATH2(src_path, src_dir_path, src_file_name);
          if (dst_new_name.size() != 0) dst_file_name = dst_new_name; else dst_file_name = src_file_name;
          COMPOSE_PATH2(dst_path, dst_dir_path, dst_file_name);
          if (dst_path == src_path) FAIL(CustomError(far_get_msg(MSG_ERR_SELF_COPY), src_path));
        }
      }

      // make sure destination path exists
      if (dst_is_remote) prepare_target_path(dst_dir_path, plugin->session, plugin);
      else prepare_target_path(dst_dir_path, plugin);

      Array<unsigned> finished_idx; // indices of processed files

      // try to move files remotely
      // mark files that were processed successfully
      if (options.move_files && dst_is_remote) {
        // prepare progress data
        CopyFilesProgress progress;
        QueryPerformanceCounter((PLARGE_INTEGER) &progress.start_time);
        ui.force_update();
        // iterate through selected files
        for (unsigned i = 0; i < ItemsNumber; i++) {
          src_file_name = panel_file_list[i].file_name; // source file name
          COMPOSE_PATH2(src_path, src_dir_path, src_file_name); // source file path
          if (dst_new_name.size() != 0) dst_file_name = dst_new_name; else dst_file_name = src_file_name; // destination file name
          COMPOSE_PATH2(dst_path, dst_dir_path, dst_file_name); // destination file path
          // update progress bar if needed
          if (ui.update_needed()) {
            progress.src_path = src_path;
            progress.dst_path = dst_path;
            draw_move_remote_files_progress(progress, stats);
          }
          // try to move file remotely
          if (move_remote_file(src_path, dst_path, plugin->session)) {
            // update stats
            if (panel_file_list[i].is_dir()) stats.dirs++;
            else stats.files++;
            // add finished file to list
            finished_idx += i;
          }
        }
      }

      // scan source directories and prepare lists of files to process
      ObjectArray<FileList> file_lists;
      ui.force_update();
      CreateListStats list_stats;
      CreateListOptions list_options;
      list_options.ignore_errors = options.ignore_errors;
      list_options.show_error = options.show_error;
      try {
        for (unsigned i = 0; i < ItemsNumber; i++) {
          if (finished_idx.bsearch(i) == -1) {
            file_lists += create_file_list(src_dir_path, panel_file_list[i].file_name, list_stats, list_options, ui, log, plugin->session, plugin);
          }
          else file_lists += FileList(); // skip already moved objects
        }
      }
      finally (stats.errors = list_stats.errors);

      // show file filters dialog if needed
      ObjectArray<FilterInterface> filters;
      if (options.use_file_filters && !dst_is_remote && show_dialog) {
        load_file_filters();
        if (export_filter_list.size() != 0) {
          Array<FilterSelection> selection;
          if (!show_filters_dlg(export_filter_list, selection)) BREAK;
          for (unsigned i = 0; i < selection.size(); i++) {
            filters += FilterInterface(export_filter_list[selection[i].src_idx].src_ext, export_filter_list[selection[i].src_idx][selection[i].dst_idx].dst_ext, export_filter_list[selection[i].src_idx][selection[i].dst_idx].guid);
          }
        }
      }

      // perform copy
      CopyFilesProgress progress;
      progress.total_size = list_stats.size;
      progress.processed_total_size = progress.copied_total_size = 0;
      QueryPerformanceCounter((PLARGE_INTEGER) &progress.start_time);
      ui.force_update();
      AutoBuffer buffer(g_plugin_options.copy_buf_size);
      for (unsigned i = 0; i < ItemsNumber; i++) {
        if (finished_idx.bsearch(i) == -1) {
          copy_files(true, src_dir_path, file_lists[i], dst_is_remote, dst_dir_path, dst_new_name, stats, progress, options, ui, buffer, log, filters, plugin->session, plugin);
        }
        PanelItem[i].Flags &= ~PPIF_SELECTED;
      }

      // delete source files if moving (only if no errors or skipped files to prevent data loss)
      if (options.move_files && (stats.errors == 0) && (stats.skipped == 0)) {
        DeleteFilesStats del_stats;
        DeleteFilesOptions del_options;
        del_options.ignore_errors = options.ignore_errors;
        del_options.show_stats = options.show_stats;
        del_options.show_error = options.show_error;
        del_options.show_dialog = options.show_dialog;
        DeleteFilesProgress del_progress;
        del_progress.objects = 0;
        del_progress.total_objects = list_stats.files + list_stats.dirs;
        QueryPerformanceCounter((PLARGE_INTEGER) &del_progress.start_time);
        ui.force_update();
        try {
          for (unsigned i = 0; i < ItemsNumber; i++) {
            delete_files(true, src_dir_path, file_lists[i], del_stats, del_progress, del_options, ui, log, plugin->session, plugin);
          }
        }
        finally (stats.errors += del_stats.errors);
      }

      // set cursor to new file name after rename
      if (dst_is_remote && options.move_files && (src_dir_path == dst_dir_path)) {
        assert(dst_new_name.size() != 0);
        far_control_int(plugin, FCTL_UPDATEPANEL, 1);
        PanelInfo panel_info;
        far_control_ptr(plugin, FCTL_GETPANELINFO, &panel_info);
        PanelRedrawInfo redraw_info = { sizeof(PanelRedrawInfo) };
        redraw_info.TopPanelItem = panel_info.TopPanelItem;
        redraw_info.CurrentItem = panel_info.CurrentItem;
        for (size_t i = 0; i < panel_info.ItemsNumber; i++) {
          PluginPanelItem* ppi = far_get_panel_item(plugin, i, panel_info);
          UnicodeString file_name = ppi->FileName;
          if (file_name == dst_new_name) {
            redraw_info.CurrentItem = i;
            break;
          }
        }
        far_control_ptr(INVALID_HANDLE_VALUE, FCTL_REDRAWPANEL, &redraw_info);
      }
    }

    if (show_dialog && ((options.show_stats == ssoAlways) || ((options.show_stats == ssoIfError) && (stats.errors != 0)))) show_copy_files_results_dlg(stats, log);
    return 1;
  }