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

📄 fax_list.cpp

📁 用于使用moden进行传真的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* Copyright (C) 2001 2002 2003 Chris VineThis program is distributed under the General Public Licence, version 2.For particulars of this and relevant disclaimers see the fileCOPYING distributed with the source files.*/#include <vector>#include <cstdlib>#include <fstream>#include <iomanip>#include <list>#include <cstring>#include <unistd.h>#include <limits.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <dirent.h>#include <stdlib.h>#include <signal.h>#include <errno.h>#ifdef HAVE_PTHREAD_SIGMASK #include <pthread.h>#endif#include <gdkmm/pixbuf.h>#include <gdk/gdkkeysyms.h> // the key codes are here#include <gtkmm/main.h>#include <gtkmm/image.h>#include <gtkmm/stock.h>#include <gtkmm/tooltips.h>#include <glibmm/convert.h>#include <glibmm/timer.h>#include <glibmm/thread.h>#include "fax_list.h"#include "dialogs.h"#include "fax_list_icons.h"#include "pipes.h"#ifdef HAVE_STRINGSTREAM#include <sstream>#else#include <strstream>#endif#ifdef ENABLE_NLS#include <libintl.h>#endifint FaxListDialog::is_fax_received_list = 0;int FaxListDialog::is_fax_sent_list = 0;FaxListDialog::FaxListDialog(Mode mode_, const int standard_size_):                              Gtk::Window(Gtk::WINDOW_TOPLEVEL),			      mode(mode_), standard_size(standard_size_),			      fax_basename_sem(1),			      fax_list_box(false, 0), table(2, 1, false),                              close_button(Gtk::Stock::CLOSE),			      button_box(Gtk::BUTTONBOX_SPREAD) {  // notify the existence of this object  if (mode == received) is_fax_received_list++;  else is_fax_sent_list++;  fax_list_scroll_window.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);  fax_list_scroll_window.add(tree_view);  fax_list_scroll_window.set_shadow_type(Gtk::SHADOW_IN);  // create the tree model:  list_store_r = Gtk::ListStore::create(model_columns);  // connect it to the tree view  tree_view.set_model(list_store_r);  // add the columns of the tree model to tree view  tree_view.append_column(gettext("Fax"), model_columns.fax_name);  tree_view.append_column(gettext("Description"), model_columns.fax_description);  // single line selection  tree_view.get_selection()->set_mode(Gtk::SELECTION_SINGLE);  // populate the fax list  get_fax_list_rows();  // set up the tool bar  tool_bar.set_orientation(Gtk::ORIENTATION_HORIZONTAL);  tool_bar.set_toolbar_style(Gtk::TOOLBAR_ICONS);  // first make the image widgets  Gtk::Image* print_image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(print_xpm)));  Gtk::Image* view_image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(view_xpm)));  Gtk::Image* describe_image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(describe_xpm)));  Gtk::Image* delete_image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(delete_xpm)));  Gtk::Image* refresh_image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(refresh_xpm)));  tool_bar.set_tooltips(true);#if GTKMM_VERSION >= 24  tool_bar.set_toolbar_style(Gtk::TOOLBAR_ICONS);  Gtk::Tooltips* tooltips_p = tool_bar.get_tooltips_object();  tooltips_p->enable();  print_button_p = manage(new Gtk::ToolButton(*print_image_p));  tool_bar.append(*print_button_p, sigc::mem_fun(*this, &FaxListDialog::print_fax_prompt));  print_button_p->set_sensitive(false);  print_button_p->set_tooltip(*tooltips_p, gettext("Print selected fax"));  view_button_p = manage(new Gtk::ToolButton(*view_image_p));  tool_bar.append(*view_button_p, sigc::mem_fun(*this, &FaxListDialog::view_fax));  view_button_p->set_sensitive(false);  view_button_p->set_tooltip(*tooltips_p, gettext("View selected fax"));  describe_button_p = manage(new Gtk::ToolButton(*describe_image_p));  tool_bar.append(*describe_button_p, sigc::mem_fun(*this, &FaxListDialog::describe_fax_prompt));  describe_button_p->set_sensitive(false);  describe_button_p->set_tooltip(*tooltips_p, gettext("Add/amend description for selected fax"));  delete_button_p = manage(new Gtk::ToolButton(*delete_image_p));  tool_bar.append(*delete_button_p, sigc::mem_fun(*this, &FaxListDialog::delete_fax_prompt));  delete_button_p->set_sensitive(false);  delete_button_p->set_tooltip(*tooltips_p, gettext("Delete selected fax"));  Gtk::ToolButton* refresh_button_p = manage(new Gtk::ToolButton(*refresh_image_p));  tool_bar.append(*refresh_button_p, sigc::mem_fun(*this, &FaxListDialog::refresh_slot));  refresh_button_p->set_tooltip(*tooltips_p, gettext("Refresh fax list"));#else  Gtk::Button* refresh_button_p;  {    using namespace Gtk::Toolbar_Helpers;        ToolList& tool_list = tool_bar.tools();    tool_list.push_back(ButtonElem(*print_image_p, SigC::slot(*this, &FaxListDialog::print_fax_prompt),				   gettext("Print selected fax")));    print_button_p = static_cast<Gtk::Button*>(tool_list.back().get_widget());    print_button_p->set_relief(Gtk::RELIEF_NONE);    print_button_p->set_sensitive(false);    tool_list.push_back(ButtonElem(*view_image_p, SigC::slot(*this, &FaxListDialog::view_fax),				   gettext("View selected fax")));    view_button_p = static_cast<Gtk::Button*>(tool_list.back().get_widget());    view_button_p->set_relief(Gtk::RELIEF_NONE);    view_button_p->set_sensitive(false);    tool_list.push_back(ButtonElem(*describe_image_p, SigC::slot(*this, &FaxListDialog::describe_fax_prompt),				   gettext("Add/amend description for selected fax")));    describe_button_p = static_cast<Gtk::Button*>(tool_list.back().get_widget());    describe_button_p->set_relief(Gtk::RELIEF_NONE);    describe_button_p->set_sensitive(false);    tool_list.push_back(ButtonElem(*delete_image_p, SigC::slot(*this, &FaxListDialog::delete_fax_prompt),				   gettext("Delete selected fax")));    delete_button_p = static_cast<Gtk::Button*>(tool_list.back().get_widget());    delete_button_p->set_relief(Gtk::RELIEF_NONE);    delete_button_p->set_sensitive(false);    tool_list.push_back(ButtonElem(*refresh_image_p, SigC::slot(*this, &FaxListDialog::refresh_slot),				   gettext("Refresh fax list")));    refresh_button_p = static_cast<Gtk::Button*>(tool_list.back().get_widget());  }#endif  button_box.add(close_button);  table.attach(fax_list_scroll_window, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL,         Gtk::EXPAND | Gtk::FILL, standard_size/3, standard_size/3);  table.attach(button_box, 0, 1, 1, 2, Gtk::EXPAND | Gtk::FILL,	 Gtk::SHRINK, standard_size/3, standard_size/3);  fax_list_box.pack_start(tool_bar, false, false);  fax_list_box.pack_start(table, true, true);  // now connect up the signal which indicates a selection has been made  tree_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FaxListDialog::set_buttons_slot));  // connect up close_button  close_button.signal_clicked().connect(sigc::mem_fun(*this, &FaxListDialog::close_slot));  close_button.set_flags(Gtk::CAN_DEFAULT);  close_button.grab_focus();  table.set_border_width(standard_size/3);  if (mode == received) set_title(gettext("efax-gtk: Received fax list"));  else set_title(gettext("efax-gtk: Sent fax list"));  //set_position(Gtk::WIN_POS_CENTER);  add(fax_list_box);  set_default_size(standard_size * 15, standard_size * 12);  set_icon(prog_config.window_icon_r);  show_all();#if GTKMM_VERSION < 24  refresh_button_p->set_relief(Gtk::RELIEF_NORMAL);#endif  refresh_button_p->set_sensitive(true);}FaxListDialog::~FaxListDialog(void) {  // notify the destruction of this object  if (mode == received) is_fax_received_list--;  else is_fax_sent_list--;}void FaxListDialog::get_fax_list_rows(void) {  std::string dir(prog_config.homedir);  if (mode == received) dir += "/faxin";  else dir += "/faxsent";  chdir(dir.c_str());  DIR* dir_p;  if ((dir_p = opendir(dir.c_str())) == 0) {    std::string msg("Can't open directory ");    msg += dir;    msg += '\n';    write_error(msg.c_str());  }  else {    struct dirent* direntry;    struct stat statinfo;    std::list<std::string> dir_list;    // first populate dir_list with the directory names in $HOME/faxin    while ((direntry = readdir(dir_p)) != 0) {      stat(direntry->d_name, &statinfo);      if (S_ISDIR(statinfo.st_mode)	  && std::strcmp(direntry->d_name, "oldfax")	  && std::strcmp(direntry->d_name, ".")	  && std::strcmp(direntry->d_name, "..")	  && (mode == sent	      || std::strcmp(direntry->d_name, prog_config.receive_dirname))) {	dir_list.push_back(direntry->d_name);      }    }    closedir(dir_p);    // now insert the directory names in fax_list, with description (if any)    // first clear the list store -- we need to clear it here before    // testing for an empty dir_list, or on deleting the last fax in the list,    // the clear won't take out the former last entry    list_store_r->clear();    if (!dir_list.empty()) {      // first sort them      dir_list.sort();            // populate the list store, and get the fax description (if any)      std::string filename;      std::string line;      std::ifstream file;      std::list<std::string>::const_iterator iter;      for (iter = dir_list.begin(); iter!= dir_list.end(); ++iter) {      	// get a list store row to insert the fax name	Gtk::TreeModel::Row row = *(list_store_r->append());	row[model_columns.fax_name] = *iter;	// now see if there is a description	filename = dir + '/';	filename += *iter;	filename += "/Description";#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 (!line.empty()) {	  try {	    row[model_columns.fax_description] = Glib::locale_to_utf8(line);	  }	  catch (Glib::ConvertError&) {	    write_error("UTF-8 conversion error in FaxListDialog::get_fax_list_rows()\n");	  }	}	filename = "";	line = "";	file.clear();	file.close();      }    }  }  // reset current directory  std::string temp(prog_config.homedir + "/faxin");  chdir(temp.c_str());}void FaxListDialog::close_slot(void) {  hide_all();  delete this; // this is completely safe as the dialog is self-owning and modeless}bool FaxListDialog::on_delete_event(GdkEventAny*) {  close_slot();  return true; // returning true prevents destroy sig being emitted}void FaxListDialog::set_buttons_slot(void) {  // see if anything is selected  if (tree_view.get_selection()->get_selected()) {    print_button_p->set_sensitive(true);    view_button_p->set_sensitive(true);    describe_button_p->set_sensitive(true);    delete_button_p->set_sensitive(true);#if GTKMM_VERSION < 24    print_button_p->set_relief(Gtk::RELIEF_NORMAL);    view_button_p->set_relief(Gtk::RELIEF_NORMAL);    describe_button_p->set_relief(Gtk::RELIEF_NORMAL);    delete_button_p->set_relief(Gtk::RELIEF_NORMAL);#endif  }      else {    print_button_p->set_sensitive(false);    view_button_p->set_sensitive(false);    describe_button_p->set_sensitive(false);    delete_button_p->set_sensitive(false);#if GTKMM_VERSION < 24    print_button_p->set_relief(Gtk::RELIEF_NONE);    view_button_p->set_relief(Gtk::RELIEF_NONE);    describe_button_p->set_relief(Gtk::RELIEF_NONE);    delete_button_p->set_relief(Gtk::RELIEF_NONE);#endif  }}void FaxListDialog::describe_fax_prompt(void) {  Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected();  if (row_iter) {    Glib::ustring description;    description = (*row_iter)[model_columns.fax_description];        DescriptionDialog* dialog_p = new DescriptionDialog(standard_size, description, *this);    dialog_p->accepted.connect(sigc::mem_fun(*this, &FaxListDialog::describe_fax));    // there is no memory leak -- the memory will be deleted when DescriptionDialog closes  }}void FaxListDialog::describe_fax(const Glib::ustring& description) {  Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected();  if (row_iter) {    (*row_iter)[model_columns.fax_description] = description;    std::string filename(prog_config.homedir);    if (mode == received) filename += "/faxin/";    else filename += "/faxsent/";    filename += (*row_iter)[model_columns.fax_name];    filename += "/Description";    std::ofstream file(filename.c_str(), std::ios::out);    // this try()/catch() block is ultra-cautious - something has gone seriously    // wrong with the program if the UTF-8 conversion fails since the source is    // a Gtk::Entry object    try {      if (file) file << Glib::locale_from_utf8(description);          else {	std::string msg("Can't open file ");	msg += filename;	msg += '\n';	write_error(msg.c_str());      }    }    catch (Glib::ConvertError&) {      write_error("UTF-8 conversion error in FaxListDialog::describe_fax()\n");    }  }}void FaxListDialog::print_fax_prompt(void) {  // we do not need a mutex before reading prog_config.print_popup, even though  // it is also read in FaxListDialog::print_fax_thread(), because it is of type  // bool which can be safely concurrently read in different threads and in any  // event it is read in FaxListDialog::print_fax_thread() in a separate process  // after fork()ing so there isn't even concurrent access  if (prog_config.print_popup) {    Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected();    // we do not need a mutex before reading prog_config.print_cmd either    // as although read in FaxListDialog::get_print_from_stdin_parms(),    // the thread which executes that method cannot start until the prompt    // dialog below is launched    if (row_iter && !prog_config.print_cmd.empty()) {      std::string faxnumber((*row_iter)[model_columns.fax_name]);      Glib::ustring msg(gettext("Print fax "));      msg += faxnumber + gettext("?");            PromptDialog* dialog_p = new PromptDialog(msg, gettext("Print fax"), standard_size, *this);      dialog_p->accepted.connect(sigc::mem_fun(*this, &FaxListDialog::print_fax));      // there is no memory leak -- the memory will be deleted when PromptDialog closes    }  }  else print_fax();}

⌨️ 快捷键说明

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