📄 mainwindow.cpp
字号:
// get the program name for the exec() call below (because this is a // multi-threaded program, we must do this before fork()ing because // we use functions to get the argument which is not async-signal-safe) std::string cmd; try { cmd.assign(Glib::filename_from_utf8(prog_config.fax_received_prog)); } catch (Glib::ConvertError&) { write_error("UTF-8 conversion error in MainWindow::fax_received_notify_slot()\n"); cmd.assign(prog_config.fax_received_prog); } // we can use the raw output of cmd.c_str() here - it will remain valid at the execlp() call const char* prog_name = cmd.c_str(); pid_t pid = fork(); if (pid == -1) { write_error("Fork error - exiting\n"); std::exit(FORK_ERROR); } if (!pid) { // child process - as soon as everything is set up we are going to do an exec() // now we have forked, we can connect MainWindow::error_pipe to stderr connect_to_stderr(); execlp (prog_name, prog_name, prog_config.receive_dirname, 0); // if we reached this point, then the execlp() call must have failed // report error and end process - use _exit() and not exit() write_error("Can't find the program to execute when a fax is received.\n" "Please check your installation and the PATH environmental variable\n"); _exit(EXEC_ERROR); } // end of child process } if (prog_config.fax_received_popup) { InfoDialog* dialog_p = new InfoDialog(gettext("A fax has been received by efax-gtk"), gettext("efax-gtk: fax received"), standard_size, Gtk::MESSAGE_INFO, *this, !is_sensitive()); dialog_p->present(); // there is no memory leak - the exec() method has not been called so the dialog // is self-owning and will delete itself when it is closed }}void MainWindow::enter_socket_file_slot(const std::pair<Glib::ustring, std::string>& fax_to_insert) { // this slot is connected to the SocketListDialog::selected_fax signal and is // called (that is, whenever the send fax button is pressed in a dialog object of // that class) // it is also connected to the SocketNotifyDialog::fax_name_sig signal, and is called // when the send fax button is pressed in a dialog object of that class // fax_to_insert.first is the fax label for the fax selected in the SocketListDialog object // and fax_to_insert.second is the real (temporary) file name obtained from mkstemp() // now show the fax label in the "Files to fax" box // in case we are called from SocketNotifyDialog::fax_name_sig (when it // is possible that the file selection buttons will be active) make // sure that the socket button is active // (we do not have to close either file selection dialogs, because if // they were open when fax_to_send_notify_slot() was called then // it would not bring up a SocketNotifyDialog object, and if a file selection // dialog was opened up after a SocketNotifyDialog object was brought up, // it would render the SocketNotifyDialog inoperative by making its parent // (this object) insensitive, so we could not reach here until it is closed) socket_button.set_active(true); // now enter the particulars of the selected file in MainWindow::selected_socket_list_file // (we will use this later to send the fax in MainWindow::sendfax_slot()) selected_socket_list_file = fax_to_insert.second; Glib::ustring socket_file_label("*** "); socket_file_label += fax_to_insert.first; socket_file_label += " ***"; set_files_slot(socket_file_label);}void MainWindow::remove_from_socket_server_filelist(const std::string& file) { socket_server.remove_file(file); // if we have stored the file name for sending, delete it // and remove from the "Fax to send" box if (file == selected_socket_list_file) { selected_socket_list_file = ""; set_files_slot(""); }}void MainWindow::set_file_items_sensitive_slot(void) { single_file_item_p->set_sensitive(true); multiple_file_item_p->set_sensitive(true); single_file_button.set_sensitive(true); multiple_file_button.set_sensitive(true); file_entry.set_editable(true); socket_list_item_p->set_sensitive(false); socket_list_button.set_sensitive(false); set_focus(single_file_button); // we now need to close the socket list dialog (if it is open), empty // the std::string object holding particulars of the currently selected // print job received from the socket server and any print job in the // Gtk::Entry object for that print job close_socket_list_dialog(); selected_socket_list_file = ""; set_files_slot("");}void MainWindow::set_socket_items_sensitive_slot(void) { single_file_item_p->set_sensitive(false); multiple_file_item_p->set_sensitive(false); single_file_button.set_sensitive(false); multiple_file_button.set_sensitive(false); file_entry.set_editable(false); socket_list_item_p->set_sensitive(true); socket_list_button.set_sensitive(true); set_focus(socket_list_button);}void MainWindow::addressbook_slot(void) { if (!AddressBook::get_is_address_list()) { AddressBook* dialog_p = new AddressBook(standard_size, *this); dialog_p->accepted.connect(sigc::mem_fun(*this, &MainWindow::set_number_slot)); // there is no memory leak -- AddressBook will delete its own memory // when it is closed }}void MainWindow::file_list_slot(void) { FileListDialog* dialog_p = new FileListDialog(standard_size, *this); dialog_p->accepted.connect(sigc::mem_fun(*this, &MainWindow::set_files_slot)); // there is no memory leak -- FaxListDialog is modeless and will delete its own memory // when it is closed}void MainWindow::settings_slot(void) { if (efax_controller.get_state() != EfaxController::inactive) { InfoDialog* dialog_p; Glib::ustring message(gettext("Can't change settings unless " "the program is inactive\n" "Press the Stop button to make it inactive")); dialog_p = new InfoDialog(message, "Change settings", standard_size, Gtk::MESSAGE_WARNING, *this); // there is no memory leak -- exec() was not called so InfoDialog // will delete its own memory when it is closed } else { SettingsDialog* dialog_p = new SettingsDialog(standard_size, *this); dialog_p->accepted.connect(sigc::mem_fun(*this, &MainWindow::settings_changed_slot)); // there is no memory leak -- SettingsDialog will delete its own memory // when it is closed }}void MainWindow::settings_changed_slot(const Glib::ustring& messages) { text_window.reset_logfile(); if (!messages.empty()) { try { text_window.write_red_slot(Glib::locale_from_utf8(messages).c_str()); text_window.write_red_slot("\n"); } catch (Glib::ConvertError&) { write_error("UTF-8 conversion error in MainWindow::settings_changed_slot()\n"); } } if ((!prog_config.sock_server || prog_config.sock_server_port.empty()) && socket_server.is_server_running()) { socket_server.stop(); } else if (prog_config.sock_server && !prog_config.sock_server_port.empty() && !socket_server.is_server_running()) { socket_server.start(std::string(prog_config.sock_server_port), prog_config.other_sock_client_address); } else if (socket_server.get_port() != std::string(prog_config.sock_server_port) || socket_server.get_other_sock_client_address() != prog_config.other_sock_client_address) { socket_server.stop(); socket_server.start(std::string(prog_config.sock_server_port), prog_config.other_sock_client_address); }}void MainWindow::helpfile_slot(void) { if (!HelpDialog::get_is_helpfile()) { helpfile_p = new HelpDialog(standard_size); } else helpfile_p->present(); // there is no memory leak -- HelpDialog is modeless and will delete its own memory // when it is closed}void MainWindow::set_number_slot(const Glib::ustring& number) { number_entry.set_text(number); if (file_entry.get_text_length()) { // reset this window as sensitive to make grab_focus() work set_sensitive(true); send_button.grab_focus(); }}void MainWindow::about_slot(bool efax_gtk) { InfoDialog* dialog_p; if (efax_gtk) { Glib::ustring message("efax-gtk-" VERSION "\n"); message += gettext("Copyright (C) 2001 - 2004 Chris Vine\n\n" "This program is released under the " "GNU General Public License, version 2"); dialog_p = new InfoDialog(message, gettext("About efax-gtk"), standard_size, Gtk::MESSAGE_INFO, *this); } else { Glib::ustring message = gettext("This program is a front end for efax.\n" "efax is a program released under the " "GNU General Public License, version 2 by Ed Casas.\n\n" "The copyright to efax is held by Ed Casas " "(the copyright to this program is held by Chris Vine)"); dialog_p = new InfoDialog(message, gettext("About efax"), standard_size, Gtk::MESSAGE_INFO, *this); } // there is no memory leak -- exec() was not called so InfoDialog // will delete its own memory when it is closed}void MainWindow::translations_slot(void) { Glib::ustring message = gettext("Italian - Luca De Rugeriis\n" "Polish - Pawel Suwinski\n" "Bulgarian - Zdravko Nikolov\n" "Russian - Pavel Vainerman\n" "Hebrew - Assaf Gillat"); new InfoDialog(message, gettext("Translations"), standard_size, Gtk::MESSAGE_INFO, *this); // there is no memory leak -- InfoDialog is modeless and will delete its own memory // when it is closed}void MainWindow::get_longest_button_text(void) { std::vector<Glib::ustring> text_vec; text_vec.push_back(gettext("Single file")); text_vec.push_back(gettext("Multiple files")); text_vec.push_back(gettext("Socket list")); text_vec.push_back(gettext("Tel number: ")); text_vec.push_back(gettext("Send fax")); text_vec.push_back(gettext("Answer call")); text_vec.push_back(gettext("Take over call")); text_vec.push_back(gettext("Standby")); text_vec.push_back(gettext("Stop")); Gtk::Button button; std::vector<Glib::ustring>::const_iterator temp_iter; std::vector<Glib::ustring>::const_iterator max_width_iter; int width; int height; int max_width; for (temp_iter = text_vec.begin(), max_width_iter = text_vec.begin(), width = 0, height = 0, max_width = 0; temp_iter != text_vec.end(); ++temp_iter) { button.create_pango_layout(*temp_iter)->get_pixel_size(width, height); if (width > max_width) { max_width = width; max_width_iter = temp_iter; } } max_text = *max_width_iter;}bool MainWindow::on_visibility_notify_event(GdkEventVisibility* event_p) { if(event_p->state == GDK_VISIBILITY_FULLY_OBSCURED) obscured = true; else obscured = false; return Gtk::Window::on_visibility_notify_event(event_p);}bool MainWindow::on_window_state_event(GdkEventWindowState* event_p) { if(event_p->new_window_state == GDK_WINDOW_STATE_ICONIFIED) minimised = true; else minimised = false; return Gtk::Window::on_window_state_event(event_p);}void MainWindow::tray_icon_left_clicked_slot(void) { // test Gtk::Window::is_visible() as well as the 'obscured' variable - if we call // hide() on the window it does not count as a visibility notify event! if (is_visible() && !obscured && !minimised && is_sensitive()) hide(); else present();}void MainWindow::tray_icon_menu_slot(int item) { switch(item) { case TrayItem::list_received_faxes: fax_list_slot(FaxListEnum::received); break; case TrayItem::list_sent_faxes: fax_list_slot(FaxListEnum::sent); break; case TrayItem::receive_answer: receive_slot(EfaxController::receive_answer); break; case TrayItem::receive_takeover: receive_slot(EfaxController::receive_takeover); break; case TrayItem::receive_standby: receive_slot(EfaxController::receive_standby); break; case TrayItem::stop: efax_controller.stop_slot(); break; case TrayItem::quit: close_slot(); break; default: break; }}void MainWindow::on_style_changed(const Glib::RefPtr<Gtk::Style>& prev_style) { // before we set the buttons, do anything else necessary with the new style Gtk::Window::on_style_changed(prev_style); //now set the buttons in MainWindow int width = 0; int height = 0; Gtk::Button button; button.set_style(get_style()); button.create_pango_layout(max_text)->get_pixel_size(width, height); // add padding width += 18; height += 12; // have some sensible minimum width and height if a very small font chosen const int min_width = standard_size * 4; const int min_height = 30; if (width < min_width) width = min_width; if (height < min_height) height = min_height; single_file_button.set_size_request(width, height); multiple_file_button.set_size_request(width, height); socket_list_button.set_size_request(width, height); number_button.set_size_request(width, height); send_button.set_size_request(width, height); receive_answer_button.set_size_request(width, height); receive_takeover_button.set_size_request(width, height); receive_standby_button.set_size_request(width, height); stop_button.set_size_request(width, height); status_line.set_colour(get_style());}bool MainWindow::draw_fax_from_socket_notifier(GdkEventExpose*) {/* This method displays the "red circle" indicator which shows a fax file received from the socket is awaiting sending. It is is called in the following circumstances: - it is connected to the signal_expose_event signal of MainWindow::drawing_area and is also called in MainWindow::socket_filelist_changed_notify_slot() - MainWindow::socket_filelist_changed_notify_slot() is connected to the Socket_server::filelist_changed_notify signal - the Socket_server::filelist_changed_notify signal is emitted by Socket_server:read_socket() when a new fax file to be sent
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -