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

📄 addressbook.cpp

📁 linux pritner GUI
💻 CPP
字号:
/* Copyright (C) 2001 2002 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 <string>#include <fstream>#include <cstdlib>#include <gtkmm/main.h>#include <gdkmm/pixbuf.h>#include <gtkmm/image.h>#include <gdk/gdkkeysyms.h> // the key codes are here#include <gtkmm/stock.h>#include <glibmm/convert.h>#include "addressbook.h"#include "dialogs.h"#include "addressbook_icons.h"#ifdef ENABLE_NLS#include <libintl.h>#endif#define ADDRESS_FILE ".efax-gtk_addressbook"#define ADDRESS_DIVIDER 3int AddressBook::is_address_list = 0;AddressBook::AddressBook(const int size, Gtk::Window& window):                             Gtk::Window(Gtk::WINDOW_TOPLEVEL), standard_size(size),			     parent(window), in_exec_loop(false),			     table(2, 1, false), list_table(5, 2, false),			     ok_button(Gtk::Stock::OK), cancel_button(Gtk::Stock::CANCEL),			     button_box(Gtk::BUTTONBOX_END, standard_size/2) {  // notify the existence of this object in case I later decide to use this dialog as modeless  // by omitting the set_modal() call below  is_address_list++;  address_list_scroll_window.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);  address_list_scroll_window.add(tree_view);  address_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("Name"), model_columns.name);  tree_view.append_column(gettext("Number"), model_columns.number);  // single line selection  tree_view.get_selection()->set_mode(Gtk::SELECTION_SINGLE);  // make drag and drop work  tree_view.set_reorderable(true);  // populate the address list  read_list();  list_store_r->signal_row_deleted().connect(sigc::mem_fun(*this, &AddressBook::drag_n_drop_slot), true);  Gtk::Image* image_p;  image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(add_xpm)));  add_button.add(*image_p);  image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(delete_xpm)));  delete_button.add(*image_p);  image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(up_arrow_xpm)));  up_button.add(*image_p);  image_p = manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(down_arrow_xpm)));  down_button.add(*image_p);  Gtk::Label* dummy_p = manage(new Gtk::Label);  list_table.attach(add_button, 0, 1, 0, 1,		    Gtk::SHRINK, Gtk::SHRINK, standard_size/2, 0);  list_table.attach(delete_button, 0, 1, 1, 2,		    Gtk::SHRINK, Gtk::SHRINK, standard_size/2, 0);  list_table.attach(up_button, 0, 1, 2, 3,		    Gtk::SHRINK, Gtk::SHRINK, standard_size/2, 0);  list_table.attach(down_button, 0, 1, 3, 4,		    Gtk::SHRINK, Gtk::SHRINK, standard_size/2, 0);  list_table.attach(*dummy_p, 0, 1, 4, 5,		    Gtk::SHRINK, Gtk::EXPAND, 0, 0);  list_table.attach(address_list_scroll_window, 1, 2, 0, 5, Gtk::EXPAND | Gtk::FILL,         Gtk::EXPAND | Gtk::FILL, 0, 0);  tooltips.set_tip(add_button, gettext("Add new address"));  tooltips.set_tip(delete_button, gettext("Delete address"));  tooltips.set_tip(up_button, gettext("Move address up"));  tooltips.set_tip(down_button, gettext("Move address down"));  button_box.add(cancel_button);  button_box.add(ok_button);  table.attach(list_table, 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::FILL | Gtk::EXPAND,	 Gtk::SHRINK, standard_size/3, standard_size/3);  add_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::add_address_prompt));  delete_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::delete_address_prompt));  ok_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::ok_slot));  cancel_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::finish));  up_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::move_up));  down_button.signal_clicked().connect(sigc::mem_fun(*this, &AddressBook::move_down));    ok_button.set_flags(Gtk::CAN_DEFAULT);  cancel_button.set_flags(Gtk::CAN_DEFAULT);  add_button.unset_flags(Gtk::CAN_FOCUS);  delete_button.unset_flags(Gtk::CAN_FOCUS);  up_button.unset_flags(Gtk::CAN_FOCUS);  down_button.unset_flags(Gtk::CAN_FOCUS);  table.set_border_width(standard_size/3);  set_title(gettext("efax-gtk: Address book"));  add(table);  set_transient_for(parent);  set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);  parent.set_sensitive(false);  set_modal(true);  set_position(Gtk::WIN_POS_CENTER_ON_PARENT);  cancel_button.grab_focus();  set_icon(prog_config.window_icon_r);  set_default_size(standard_size * 15, standard_size * 8);  show_all();}AddressBook::~AddressBook(void) {  // notify the destruction of this object  is_address_list--;}Glib::ustring AddressBook::exec(void) {  in_exec_loop = true;  Gtk::Main::run();  return result;}void AddressBook::ok_slot(void) {  result = get_number();  if (!result.empty()) {    accepted(result);    finish();  }  else beep();}void AddressBook::finish(void) {  parent.set_sensitive(true);  hide_all();  if (in_exec_loop) Gtk::Main::quit();  // if we have not called exec(), then this dialog is self-owning and it is safe to call `delete this'  else delete this;}bool AddressBook::on_delete_event(GdkEventAny*) {  finish();  return true; // returning true prevents destroy sig being emitted}Glib::ustring AddressBook::get_number(void) {  Glib::ustring number;  Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected();  if (row_iter) {    number = (*row_iter)[model_columns.number];  }  return number;}void AddressBook::add_address_prompt(void) {  AddressDialog* dialog_p = new AddressDialog(standard_size, *this);  dialog_p->accepted.connect(sigc::mem_fun(*this, &AddressBook::add_address));  // there is no memory leak -- AddressDailog will delete its own memory  // when it is closed}void AddressBook::add_address(const std::vector<Glib::ustring>& address) {  Gtk::TreeModel::Row row = *(list_store_r->append());  row[model_columns.name] = address[0];  row[model_columns.number] = address[1];  save_list();}void AddressBook::delete_address_prompt(void) {  Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected();  if (row_iter) {    PromptDialog* dialog_p = new PromptDialog(gettext("Delete selected address?"),					      gettext("Delete address"), standard_size, *this);    dialog_p->accepted.connect(sigc::bind(sigc::mem_fun(*this, &AddressBook::delete_address), row_iter));    // there is no memory leak -- the memory will be deleted when PromptDialog closes  }  else beep();}void AddressBook::delete_address(Gtk::TreeModel::iterator row_iter) {  // delete the address by removing it from the list store  list_store_r->erase(row_iter);  save_list();}void AddressBook::read_list(void) {  std::string filename(prog_config.working_dir);  filename += "/" ADDRESS_FILE;#ifdef HAVE_IOS_NOCREATE  std::ifstream filein(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  std::ifstream filein(filename.c_str(), std::ios::in);#endif  if (filein) {        list_store_r->clear();    std::string line;    while (std::getline(filein, line)) {      if (!line.empty()) {	std::string::size_type pos = line.find(ADDRESS_DIVIDER, 0); // pos now is set to end of name value	// get a list store row to insert the number and  name	Gtk::TreeModel::Row row = *(list_store_r->append());	try {	  row[model_columns.name] = Glib::locale_to_utf8(line.substr(0, pos));	}	catch (Glib::ConvertError&) {	  write_error("UTF-8 conversion error in AddressBook::read_list()\n");	}	pos++; // pos now is set to the beginning of the number value	try {	  row[model_columns.number] = Glib::locale_to_utf8(line.substr(pos, line.size() - pos));	}	catch (Glib::ConvertError&) {	  write_error("UTF-8 conversion error in AddressBook::read_list()\n");	}      }    }  }}void AddressBook::save_list(void) {  std::string filename(prog_config.working_dir);  filename += "/" ADDRESS_FILE;  std::ofstream fileout(filename.c_str(), std::ios::out);  if (fileout) {        std::string line;    Gtk::TreeModel::Children children = list_store_r->children();    Gtk::TreeModel::Children::iterator row_iter;    for(row_iter = children.begin(); row_iter != children.end(); ++row_iter) {      // the try()/catch() blocks here are ultra cautious - something must be      // seriously wrong if model_columns.name and model_columns.number are not      // in valid UTF-8 format, since they are tested where necessary at input      try {	line = Glib::locale_from_utf8((*row_iter)[model_columns.name]);	line += ADDRESS_DIVIDER;	line += Glib::locale_from_utf8((*row_iter)[model_columns.number]);	line += '\n';	fileout << line;      }      catch (Glib::ConvertError&) {	write_error("UTF-8 conversion error in AddressBook::save_list()\n");      }    }  }}void AddressBook::drag_n_drop_slot(const Gtk::TreeModel::Path&) {  save_list();}void AddressBook::move_up(void) {  Gtk::TreeModel::iterator selected_row_iter = tree_view.get_selection()->get_selected();  if (selected_row_iter && selected_row_iter != list_store_r->children().begin()) {    Gtk::TreeModel::Path tree_path(selected_row_iter);    tree_path.prev(); // tree_path now refers to the row of the list store                      // preceding the selected one    Gtk::TreeModel::iterator prev_row_iter = list_store_r->get_iter(tree_path);    Glib::ustring selected_name = (*selected_row_iter)[model_columns.name];    Glib::ustring selected_number = (*selected_row_iter)[model_columns.number];    Glib::ustring prev_name = (*prev_row_iter)[model_columns.name];    Glib::ustring prev_number = (*prev_row_iter)[model_columns.number];          (*selected_row_iter)[model_columns.name] = prev_name;    (*selected_row_iter)[model_columns.number] = prev_number;    (*prev_row_iter)[model_columns.name] = selected_name;    (*prev_row_iter)[model_columns.number] = selected_number;    tree_view.get_selection()->select(prev_row_iter);    save_list();  }  else beep();}void AddressBook::move_down(void) {  Gtk::TreeModel::iterator selected_iter = tree_view.get_selection()->get_selected();  if (selected_iter) {    Gtk::TreeModel::iterator succeding_iter = selected_iter;    ++succeding_iter;       if (succeding_iter != list_store_r->children().end()) {      Glib::ustring selected_name = (*selected_iter)[model_columns.name];      Glib::ustring selected_number = (*selected_iter)[model_columns.number];      Glib::ustring succeding_name = (*succeding_iter)[model_columns.name];      Glib::ustring succeding_number = (*succeding_iter)[model_columns.number];            (*selected_iter)[model_columns.name] = succeding_name;      (*selected_iter)[model_columns.number] = succeding_number;      (*succeding_iter)[model_columns.name] = selected_name;      (*succeding_iter)[model_columns.number] = selected_number;      tree_view.get_selection()->select(succeding_iter);      save_list();    }    else beep();  }  else beep();}AddressDialog::AddressDialog(const int standard_size, Gtk::Window& window):                             Gtk::Window(Gtk::WINDOW_TOPLEVEL), in_exec_loop(false),			     ok_button(Gtk::Stock::OK), cancel_button(Gtk::Stock::CANCEL),			     button_box(Gtk::BUTTONBOX_END, standard_size/2),			     name_label(gettext("Name:")), number_label(gettext("Number:")),			     table(3, 1, false), parent(window) {  name_label.set_size_request(standard_size * 2, standard_size);  number_label.set_size_request(standard_size * 2, standard_size);  name_entry.set_size_request(standard_size * 8, standard_size);  number_entry.set_size_request(standard_size * 8, standard_size);  name_box.pack_start(name_label, false, false, standard_size/2);  name_box.pack_start(name_entry, true, true, 0);  number_box.pack_start(number_label, false, false, standard_size/2);  number_box.pack_start(number_entry, true, true, 0);  button_box.add(cancel_button);  button_box.add(ok_button);  table.attach(name_box, 0, 1, 0, 1, Gtk::FILL | Gtk::EXPAND,	 Gtk::FILL | Gtk::EXPAND, standard_size/2, standard_size/4);  table.attach(number_box, 0, 1, 1, 2, Gtk::FILL | Gtk::EXPAND,	 Gtk::FILL | Gtk::EXPAND, standard_size/2, standard_size/4);  table.attach(button_box, 0, 1, 2, 3, Gtk::FILL | Gtk::EXPAND,	 Gtk::SHRINK, standard_size/2, standard_size/4);  ok_button.signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &AddressDialog::selected), true));  cancel_button.signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &AddressDialog::selected), false));  add(table);    set_title(gettext("Add Address"));  set_transient_for(parent);  set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);  parent.set_sensitive(false);  set_modal(true);  set_border_width(standard_size/2);  name_entry.grab_focus();  set_position(Gtk::WIN_POS_CENTER_ON_PARENT);  set_resizable(false);  set_icon(prog_config.window_icon_r);  show_all();}void AddressDialog::exec(void) {  in_exec_loop = true;  Gtk::Main::run();}void AddressDialog::selected(bool accept) {  // check pre-conditions to closing the dialog  if (accept && (!name_entry.get_text_length() || !number_entry.get_text_length())) beep();    else {       parent.set_sensitive(true); // do this before we emit accepted()    hide_all();    if (accept) {      std::vector<Glib::ustring> out_val;      out_val.push_back(name_entry.get_text());      out_val.push_back(number_entry.get_text());      accepted(out_val);    }    if (in_exec_loop) Gtk::Main::quit();    // if we have not called exec(), then this dialog is self-owning and it is safe to call `delete this'    else delete this;  }}bool AddressDialog::on_delete_event(GdkEventAny*) {  selected(false);  return true; // returning true prevents destroy sig being emitted}bool AddressDialog::on_key_press_event(GdkEventKey* event_p) {  if (event_p->keyval == GDK_Escape) selected(false);  else if (event_p->keyval == GDK_Return && !cancel_button.has_focus()) selected(true);  else Gtk::Window::on_key_press_event(event_p);  return true; // processing ends here}

⌨️ 快捷键说明

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