⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fax_list_manager.cpp

📁 linux pritner GUI
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    TreeModelRowReference folder_row_ref(folder_tree_store_r, Gtk::TreePath(base_folder_row));    folder_to_row_map.insert(FolderToRowMap::value_type(base_path, folder_row_ref));    if (!dir_list.empty()) {      // first sort them      dir_list.sort();            // populate the tree store, and get the fax description (if any)      std::string filename;      std::string line;      std::ifstream file;      filename = dir;      filename += "/PathList";#ifdef HAVE_IOS_NOCREATE      file.open(filename.c_str(), std::ios::in | std::ios::nocreate);#else      // we must have Std C++ so we probably don't need a ios::nocreate      // flag on a read open to ensure uniqueness      file.open(filename.c_str(), std::ios::in);#endif      if (file) {	while (std::getline(file, line)) get_folders(folder_to_row_map, line);      }      filename = "";      line = "";      file.close();      file.clear();      std::list<std::string>::const_iterator iter;      for (iter = dir_list.begin(); iter!= dir_list.end(); ++iter) {	// get the fax list Path for each fax	filename = dir + '/';	filename += *iter;	filename += "/Path";#ifdef HAVE_IOS_NOCREATE	file.open(filename.c_str(), std::ios::in | std::ios::nocreate);#else	// we must have Std C++ so we probably don't need a ios::nocreate	// flag on a read open to ensure uniqueness	file.open(filename.c_str(), std::ios::in);#endif	if (file) {	  while (std::getline(file, line) && line.empty());	}	if (!Glib::ustring(line).validate()) {   // not valid UTF-8!	  write_error("Invalid UTF-8 string in folder path name in FaxListManager::populate_fax_list()\n");	  line = "";	}	// sort the faxes into a multimap keyed by the folder and indicating	// the faxes belong to that folder, and then enter the faxes into a	// map keyed by the fax and indicating its folder path (this gives	// faster look up of the fax to its folder by enabling a binary search	// in both directions)	if (line.size() == 1 && line[0] == PATH_DIVIDER) {	  folder_to_fax_map.insert(FolderToFaxMap::value_type(base_path, *iter));	  fax_to_folder_map.insert(FaxToFolderMap::value_type(*iter, base_path));	}	// include a call to get_folders() in case something has gone wrong	// and the fax belongs to a folder not listed in the PathList file	else if (!line.empty() && get_folders(folder_to_row_map, line)) {	  folder_to_fax_map.insert(FolderToFaxMap::value_type(line, *iter));	  fax_to_folder_map.insert(FaxToFolderMap::value_type(*iter, line));	}	else {	  folder_to_fax_map.insert(FolderToFaxMap::value_type(base_path, *iter));	  fax_to_folder_map.insert(FaxToFolderMap::value_type(*iter, base_path));	}	filename = "";	line = "";	file.close();	file.clear();      }    }    // write path in case this is the first time the program has started or    // something else has changed    write_path();    // select the main folder    Glib::ustring base_folder;    if (mode == FaxListEnum::received) base_folder = gettext("Inbox");    else base_folder = gettext("Sent box");    bool found_it = false;    Gtk::TreeModel::Children children = folder_tree_store_r->children();    Gtk::TreeModel::iterator row_iter = children.begin();    while (!found_it && row_iter != children.end()) {      if ((*row_iter)[folder_model_columns.name] == base_folder) found_it = true;      else ++row_iter;    }    if (found_it) {      folder_tree_view.get_selection()->select(row_iter);      display_faxes_slot();    }  }  // reset current directory  std::string temp(prog_config.working_dir + "/faxin");  chdir(temp.c_str());}bool FaxListManager::get_folders(FolderToRowMap& folder_to_row_map, const std::string& line) {  bool return_val;  if (!line.empty())  return_val = true;  else return_val = false;  std::vector<std::string> child_rowlist;  std::string remaining_path(line);  if (!Glib::ustring(line).validate()) { // not valid UTF-8!    write_error("Invalid UTF-8 string in folder path name in FaxListManager::get_folders()\n");    remaining_path = "";    return_val = false;  }  // keep going until we get to the root tree store or to a parent row in existence  while (!remaining_path.empty() && folder_to_row_map.find(remaining_path) == folder_to_row_map.end()) {    std::string::size_type pos = remaining_path.rfind(PATH_DIVIDER);    if (pos == std::string::npos) {  // input error      remaining_path = "";      child_rowlist.clear();      return_val = false;    }    else {      child_rowlist.push_back(remaining_path.substr(pos + 1));      folder_name_validator.insert_folder_name(remaining_path.substr(pos + 1));      remaining_path.resize(pos);    }  }  // now create the missing child level(s) stored in child_rowlist  if (!child_rowlist.empty()) {    std::vector<std::string>::reverse_iterator r_iter = child_rowlist.rbegin();    TreeModelRowReference row_ref;    std::string pathname(remaining_path);    pathname += PATH_DIVIDER;    pathname += *r_iter;    if (remaining_path.empty()) { // we need to make a first level node      Gtk::TreeModel::Row row = *folder_tree_store_r->append();      // no need for a Glib conversion function here - we store folder      // names in Path in UTF-8      row[folder_model_columns.name] = *r_iter;      row[folder_model_columns.root_only] = false;      row[folder_model_columns.icon] = folder_icon_r;      row_ref = TreeModelRowReference(folder_tree_store_r, Gtk::TreePath(row));      folder_to_row_map.insert(FolderToRowMap::value_type(pathname, row_ref));    }    else {                        // build on the nearest ancestor already created      row_ref = folder_to_row_map[remaining_path];      Gtk::TreeModel::Row row = *folder_tree_store_r->append(folder_tree_store_r->get_iter(row_ref.get_path())->children());      // TODO if (!row)      // no need for a Glib conversion function here - we store folder      // names in Path in UTF-8      row[folder_model_columns.name] = *r_iter;      row[folder_model_columns.root_only] = false;      row[folder_model_columns.icon] = folder_icon_r;      row_ref = TreeModelRowReference(folder_tree_store_r, Gtk::TreePath(row));      folder_to_row_map.insert(FolderToRowMap::value_type(pathname, row_ref));    }    // now deal with any further children remaining to be created    for (++r_iter; r_iter != child_rowlist.rend(); ++r_iter) {      Gtk::TreeModel::Row row = *folder_tree_store_r->append(folder_tree_store_r->get_iter(row_ref.get_path())->children());      // no need for a Glib conversion function here - we store folder      // names in Path in UTF-8      row[folder_model_columns.name] = *r_iter;      row[folder_model_columns.root_only] = false;      row[folder_model_columns.icon] = folder_icon_r;      pathname += PATH_DIVIDER;      pathname += *r_iter;      row_ref = TreeModelRowReference(folder_tree_store_r, Gtk::TreePath(row));      folder_to_row_map.insert(FolderToRowMap::value_type(pathname, row_ref));    }  }  return return_val;}void FaxListManager::move_fax(const Gtk::TreeModel::iterator& folder_iter, const std::string& faxname) {  // check pre-conditions  if (!drag_row_iter) return;  std::string source_pathname(fax_to_folder_map[faxname]);  std::string dest_pathname(get_pathname_for_folder(folder_iter));  if (source_pathname == dest_pathname) return;  if (fax_to_folder_map.find(faxname) != fax_to_folder_map.end()) {    fax_to_folder_map[faxname] = dest_pathname;  }  else write_error("Database mapping error in FaxListManager::move_fax()\n");  std::pair<FolderToFaxMap::iterator,            FolderToFaxMap::iterator> result(folder_to_fax_map.equal_range(source_pathname));    if (result.first == result.second) {    write_error("Equal range: database mapping error in FaxListManager::move_fax()\n");    return;  }  FolderToFaxMap::iterator iter = result.first;  bool found_it = false;  while (!found_it && iter != result.second) {    if (iter->second == faxname) {      found_it = true;      folder_to_fax_map.erase(iter);      folder_to_fax_map.insert(FolderToFaxMap::value_type(dest_pathname, faxname));      fax_list_store_r->erase(drag_row_iter);      drag_row_iter = fax_list_store_r->children().end();    }    else ++iter;  }  if (!found_it) {    write_error("Fax to move not found: database mapping error in FaxListManager::move_fax()\n");  }  write_path();}void FaxListManager::move_folder(Gtk::TreeModel::iterator folder_iter,				 Gtk::TreeViewDropPosition drop_pos,				 const std::string& foldername) {  // check pre-conditions  if (!drag_row_iter) return;  std::string source_pathname(get_pathname_for_folder(drag_row_iter));  std::string drop_pathname(get_pathname_for_folder(folder_iter));  if (source_pathname != drop_pathname) {    // get the new pathname for the folder and put it in new_pathname    std::string new_pathname(drop_pathname);    std::string::size_type pos;    if (drop_pos == Gtk::TREE_VIEW_DROP_BEFORE	|| drop_pos == Gtk::TREE_VIEW_DROP_AFTER) {      if ((pos = new_pathname.rfind(PATH_DIVIDER)) != std::string::npos) {	new_pathname.resize(pos);      }      else {	write_error("Folder with no pathname in FaxListManager::move_folder()\n");	new_pathname = "";      }    }    new_pathname += PATH_DIVIDER;    new_pathname += foldername;    if (is_valid_drop_path(source_pathname, new_pathname)	&& (!(*drag_row_iter)[folder_model_columns.root_only]	    || new_pathname.rfind(PATH_DIVIDER) == 0)) {      Gtk::TreeModel::iterator new_row_iter;      switch (drop_pos) {      case Gtk::TREE_VIEW_DROP_BEFORE:	new_row_iter = folder_tree_store_r->insert(folder_iter);	break;      case Gtk::TREE_VIEW_DROP_AFTER:	new_row_iter = folder_tree_store_r->insert(++folder_iter);	break;      default:	new_row_iter = folder_tree_store_r->prepend(folder_iter->children());	break;      }      (*new_row_iter)[folder_model_columns.name] = Glib::ustring(foldername);      bool is_root_only = (*drag_row_iter)[folder_model_columns.root_only];      (*new_row_iter)[folder_model_columns.root_only] = is_root_only;      (*new_row_iter)[folder_model_columns.icon] = folder_icon_r;      bool adjust_mapping = false;      if (source_pathname != new_pathname) {	remap_faxes_in_folder(source_pathname, new_pathname);	// and make sure that move_child_folders_for_level() also adjusts mapping	adjust_mapping = true;      }      // now move all the children of the move folder to rejoin their parent      move_child_folders_for_level(drag_row_iter->children(), new_row_iter->children(),				   source_pathname, new_pathname, adjust_mapping);      folder_tree_store_r->erase(drag_row_iter);      drag_row_iter = folder_tree_store_r->children().end();      write_path();    }  }}bool FaxListManager::is_valid_drop_path(const std::string& old_pathname,					const std::string& new_pathname) {  // check that the folder is not being dropped on one of its children -  // with drag and drop syncing issues this can happen  if (new_pathname.find(old_pathname) == 0      && new_pathname.size() > old_pathname.size()) { // we can have the new pathname the same                                                      // as the old pathname - say if folder                                                      // is being moved at same level    return false;  }  return true;}void FaxListManager::remap_faxes_in_folder(const std::string& old_pathname,					   const std::string& new_pathname) {    // this method adjusts the mapping for the faxes in a moved folder  // before calling it check that old_pathname != new_pathname  // otherwise this method will just waste time  // first get a listing of the faxes in the folder being moved  std::vector<std::string> fax_list;  std::pair<FolderToFaxMap::iterator,            FolderToFaxMap::iterator> result(folder_to_fax_map.equal_range(old_pathname));  FolderToFaxMap::iterator map_iter;  for (map_iter = result.first; map_iter != result.second; ++map_iter) {    fax_list.push_back(map_iter->second);  }  // erase old elements  folder_to_fax_map.erase(result.first, result.second);  // insert new ones  std::vector<std::string>::iterator vec_iter;  for (vec_iter = fax_list.begin(); vec_iter != fax_list.end(); ++vec_iter) {    folder_to_fax_map.insert(FolderToFaxMap::value_type(new_pathname, *vec_iter));    fax_to_folder_map[*vec_iter] = new_pathname;  }}void FaxListManager::move_child_folders_for_level(const Gtk::TreeModel::Children& source_level,						  const Gtk::TreeModel::Children& dest_level,						  const std::string& source_level_pathname,						  const std::string& dest_level_pathname,						  bool adjust_mapping) {  if (source_level && !source_level.empty()) {    Gtk::TreeModel::Children::iterator source_row_iter;    for (source_row_iter = source_level.begin(); source_row_iter != source_level.end();	 ++source_row_iter) {      std::string node_name = Glib::ustring((*source_row_iter)[folder_model_columns.name]);      std::string full_source_pathname(source_level_pathname);      full_source_pathname += PATH_DIVIDER;      full_source_pathname += node_name;      std::string full_dest_pathname(dest_level_pathname);      full_dest_pathname += PATH_DIVIDER;      full_dest_pathname += node_name;      Gtk::TreeModel::Children::iterator dest_row_iter = folder_tree_store_r->append(dest_level);      (*dest_row_iter)[folder_model_columns.name] = Glib::ustring(node_name);      // as we are not at the root level we know folder_model_columns.root_only must be false      (*dest_row_iter)[folder_model_columns.root_only] = false;      (*dest_row_iter)[folder_model_columns.icon] = folder_icon_r;      if (adjust_mapping) remap_faxes_in_folder(full_source_pathname, full_dest_pathname);            // now recursively work the way up children of this node (if any)      move_child_folders_for_level(source_row_iter->children(), dest_row_iter->children(),				   full_source_pathname, full_dest_pathname, adjust_mapping);    }  }}std::string FaxListManager::get_pathname_for_folder(Gtk::TreeModel::iterator folder_iter) {  std::string pathname;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -