/* $Id: gui.cc,v 1.16 2005/07/10 20:24:17 atterer Exp $ -*- C++ -*- __ _ |_) /| Copyright (C) 2001-2003 | richard@ | \/¯| Richard Atterer | atterer.net ¯ '` ¯ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2. See the file COPYING for details. Interface to GTK GUI. Sets up global variables pointing to the main GUI elements. "Glue code" between the interface as generated by glade (in gtk-interface.*, gtk-support.*) and jigdo's functionality. */ #include #include #include #include #include #include #include #include #include #include //______________________________________________________________________ DEBUG_UNIT("gui") /* Not all of these are set up during create() - we rely on the vars being initialized to 0 in that case. */ GUI::Window GUI::window; GUI::Filesel GUI::filesel; GUI::License GUI::license; //______________________________________________________________________ // File selection dialogue - helper functions namespace { using namespace GUI; GtkEntry* filesel_state = 0; // Private function for filesel_open below void on_filesel_okButton(GtkWidget*, gpointer) { if (filesel_state != 0) { // Copy over filename to the right GtkEntry GtkFileSelection* fileselObj = GTK_FILE_SELECTION(filesel.filesel); gtk_entry_set_text(filesel_state, gtk_file_selection_get_filename(fileselObj)); } gtk_widget_hide(filesel.filesel); // Close file selection window } /* Called to open filesel on e.g. a button click. When filesel's OK button is clicked, the selected filename is copied to "entry". */ void filesel_open(GtkWidget*, gpointer entry) { gtk_widget_show(filesel.filesel); filesel_state = GTK_ENTRY(entry); } } //______________________________________________________________________ /* Initialisation of the GUI. Mostly does some post-processing of the glade-generated data structures, connecting button press events to the corresponding function etc. */ void GUI::create() { debug("create"); window.create(); filesel.create(); GUI::jobList.postGtkInit(); /* Remove tabs from main window notebook, since the user is only allowed to switch between the pages using clicks on buttons/list entries. */ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window.invisibleNotebook),FALSE); // Set background white for jigdo welcome screen GdkColor white; gdk_color_parse("white", &white); gtk_widget_modify_bg(window.aboutBgnd, GTK_STATE_NORMAL, &white); // GtkRcStyle* aboutStyle = gtk_widget_get_modifier_style(window.aboutBgnd); // gdk_color_parse("white", &aboutStyle->bg[0]); // ... modify style - how? // gtk_widget_modify_style(window.aboutBgnd, aboutStyle); gtk_widget_set_name(window.aboutBgnd, "aboutBgnd"); gtk_rc_parse_string("style \"whitebg\" { bg[NORMAL] = \"white\" }"); // base[NORMAL] = \"white\" gtk_rc_parse_string("widget \"aboutBgnd\" style \"whitebg\""); // Set string "Jigsaw Download x.y.z" on welcome screen GtkLabel* aboutJigdoLabel = GTK_LABEL(GUI::window.aboutJigdoLabel); string banner = subst(_( "" "Jigsaw Download %F1\n" "Copyright 2001-%2 Richard Atterer\n" "http://atterer.net/jigdo"), JIGDO_VERSION, CURRENT_YEAR); gtk_label_set_markup(aboutJigdoLabel, banner.c_str()); gtk_label_set_justify(aboutJigdoLabel, GTK_JUSTIFY_CENTER); //gtk_label_set_justify(GTK_LABEL(GUI::window.aboutJigdoButtonLabel), // GTK_JUSTIFY_CENTER); gtk_label_set_markup(GTK_LABEL(GUI::window.aboutJigdoButtonLabel), _( "This is Free Software, distributable under the " "terms of the GNU GPL v2.")); // Set width of image_Info label to something bigger than the default GtkRequisition infoReq; gtk_widget_size_request(GUI::window.window, &infoReq); //gtk_widget_get_size_request(GUI::window.jigdo_InfoVbox, &infoReq.width, //&infoReq.height); debug("updateWindow width=%1", infoReq.width); int width = infoReq.width - 100; if (width < 200) width = 450; gtk_widget_set_size_request(GUI::window.jigdo_Info, width, -1); /* Handler to copy filename to right GtkEntry when OK is pressed in filesel */ g_signal_connect(G_OBJECT(filesel.okButton), "clicked", G_CALLBACK(on_filesel_okButton), NULL); /* Open filesel window when buttons are clicked, enter result in appropriate GtkEntry */ g_signal_connect(G_OBJECT(window.open_URLSel), "clicked", G_CALLBACK(filesel_open), G_OBJECT(window.open_URL)); g_signal_connect(G_OBJECT(window.open_destSel), "clicked", G_CALLBACK(filesel_open), G_OBJECT(window.open_dest)); gtk_widget_hide_all(window.toolbarReuse); # if WINDOWS gtk_entry_set_text(GTK_ENTRY(window.open_dest), g_get_home_dir()); # else char* cwd = g_get_current_dir(); gtk_entry_set_text(GTK_ENTRY(window.open_dest), cwd); g_free(cwd); # endif # if DEBUG gtk_entry_set_text(GTK_ENTRY(window.open_URL), //"ftp://localhost/image" //"http://localhost:8000/~richard/ironmaiden/part32" # if WINDOWS "http://192.168.1.5:8000/~richard/ironmaiden/image.jigdo" # else "http://127.0.0.1:8000/~richard/ironmaiden/image.jigdo" # endif ); # endif debug("create end"); } //______________________________________________________________________ // Callback handlers void on_toolbarExit_clicked(GtkButton*, gpointer) { gtk_main_quit(); } gboolean on_window_delete_event(GtkWidget*, GdkEvent*, gpointer) { gtk_main_quit(); return TRUE; } void setNotebookPage(GtkWidget* pageObject) { GUI::jobList.setWindowOwner(0); GtkNotebook* notebook = GTK_NOTEBOOK(pageObject->parent); gboolean sensitive = (pageObject == GUI::window.pageOpen ? FALSE : TRUE); gtk_widget_set_sensitive(GUI::window.toolbarOpen, sensitive); gtk_notebook_set_current_page(notebook, gtk_notebook_page_num(notebook, pageObject)); } void on_openButton_clicked(GtkButton*, gpointer) { /* Create either a JobLine to download a single file, or one to process a .jigdo file, and GUI::jobList.append() it. */ const char* uri = gtk_entry_get_text(GTK_ENTRY(window.open_URL)); const char* dest = gtk_entry_get_text(GTK_ENTRY(window.open_dest)); JobLine::create(uri, dest); } //________________________________________ namespace { // Set up a text buffer which displays the jigdo license void setLicenseText(GtkTextBuffer* textBuf) { GtkTextTag* large = gtk_text_buffer_create_tag( textBuf, NULL, "scale", 2.0, NULL); GtkTextTag* center = gtk_text_buffer_create_tag( textBuf, NULL, "justification", GTK_JUSTIFY_CENTER, NULL); GtkTextIter iter; gtk_text_buffer_get_end_iter(textBuf, &iter); gtk_text_buffer_insert_with_tags(textBuf, &iter, _("\nJigsaw Download License\n"), -1, large, center, NULL); string copy = subst(_("\n" "\tCopyright © 2001-%1 Richard Atterer \n" "\tJigsaw Download homepage: http://atterer.net/jigdo\n" "\n"), CURRENT_YEAR, '@'); gtk_text_buffer_insert_with_tags(textBuf, &iter, copy.c_str(), -1, center, NULL); gtk_text_buffer_insert(textBuf, &iter, _( "Jigsaw Download is free software; you can redistribute it and/or " "modify it under the terms of the GNU General Public License, version " "2, as published by the Free Software Foundation.\n" "\n" "In addition, as a special exception, the author gives permission " "to link the jigdo code with the OpenSSL project's \"OpenSSL\" library " "(or with modified versions of it that use the same license as the " "\"OpenSSL\" library), and to distribute the linked executables.\n"), -1); gtk_text_buffer_insert_with_tags(textBuf, &iter, "______________________________\n\n", -1, center, NULL); gtk_text_buffer_insert(textBuf, &iter, _( "Please note: The copyright notice below only applies to the text of " "the GNU General Public License; the copyright of the program is as " "specified above. Also note that jigdo is licensed under GPL version " "_2_ and no other version.\n" "\n\n"), -1); string copying = packageDataDir; copying += "COPYING"; static const int BUF_SIZE = 1024; char buf[BUF_SIZE]; ifstream file(copying.c_str()); while (file) { file.read(buf, BUF_SIZE); size_t n = file.gcount(); for (size_t i = 1; i < n - 2; ++i) { // Very simple reformatting if (buf[i] == '\f') buf[i] = '\n'; else if (buf[i] == '\n' && buf[i - 1] != '\n' && isgraph(buf[i + 1])) buf[i] = ' '; else if (buf[i] == '\n') { } // Whoa, we're supposed to be outputting UTF8 - just delete non-ASCII else if ((buf[i] < 32 || buf[i] >= 127) && buf[i] != '\t') buf[i] = '?'; } gtk_text_buffer_insert(textBuf, &iter, buf, file.gcount()); } if (!file.eof() && !file) { string err = subst(_("Error loading `%LE1': %LE2"), copying, strerror(errno)); gtk_text_buffer_insert(textBuf, &iter, err.c_str(), -1); } } } // namespace //________________________________________ // Display jigdo license void on_aboutJigdoButton_clicked(GtkButton*, gpointer) { if (GUI::license.license == 0) { GUI::license.create(); GtkTextView* view = GTK_TEXT_VIEW(GUI::license.licenseText); GtkTextBuffer* textBuf = gtk_text_view_get_buffer(view); setLicenseText(textBuf); GtkTextIter iter; gtk_text_buffer_get_start_iter(textBuf, &iter); gtk_text_buffer_place_cursor(textBuf, &iter); GdkGeometry geom; geom.min_width = geom.min_height = 1; gtk_window_set_geometry_hints(GTK_WINDOW(GUI::license.license), GUI::license.licenseText, &geom, GDK_HINT_MIN_SIZE); } gtk_window_present(GTK_WINDOW(GUI::license.license)); } //________________________________________ void on_download_startButton_clicked(GtkButton*, gpointer) { GtkSingleUrl* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_startButton_clicked(); } void on_download_pauseButton_clicked(GtkButton*, gpointer) { GtkSingleUrl* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_pauseButton_clicked(); } void on_download_stopButton_clicked(GtkButton*, gpointer) { GtkSingleUrl* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_stopButton_clicked(); } void on_download_restartButton_clicked(GtkButton*, gpointer) { GtkSingleUrl* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_restartButton_clicked(); } void on_download_closeButton_clicked(GtkButton*, gpointer) { GtkSingleUrl* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_closeButton_clicked(); } void on_download_startButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.download_buttonInfo), _("Continue download (after Pause) or " "Resume it (after Stop)")); } void on_download_pauseButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.download_buttonInfo), _("Pause download, but leave connection " "to server open")); } void on_download_stopButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.download_buttonInfo), _("Stop download by closing the connection")); } void on_download_restartButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.download_buttonInfo), _("Restart download - the data downloaded so " "far is discarded")); } void on_download_closeButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.download_buttonInfo), _("Close this download and remove it from the " "list below")); } void on_download_button_leave(GtkButton*, gpointer) { gtk_label_set_text(GTK_LABEL(GUI::window.download_buttonInfo), ""); } //________________________________________ void on_jigdo_startButton_clicked(GtkButton*, gpointer) { GtkMakeImage* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_startButton_clicked(); } void on_jigdo_pauseButton_clicked(GtkButton*, gpointer) { GtkMakeImage* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_pauseButton_clicked(); } void on_jigdo_stopButton_clicked(GtkButton*, gpointer) { GtkMakeImage* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_stopButton_clicked(); } void on_jigdo_restartButton_clicked(GtkButton*, gpointer) { GtkMakeImage* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_restartButton_clicked(); } void on_jigdo_closeButton_clicked(GtkButton*, gpointer) { GtkMakeImage* j = dynamic_cast(GUI::jobList.windowOwner()); if (j != 0) j->on_closeButton_clicked(); } void on_jigdo_startButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.jigdo_buttonInfo), _("Continue all child downloads (after Pause) " "or Resume them (after Stop or error)")); } void on_jigdo_pauseButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.jigdo_buttonInfo), _("Pause all child downloads, but leave " "connections to servers open")); } void on_jigdo_stopButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.jigdo_buttonInfo), _("Stop download by closing connections of " "all children")); } void on_jigdo_restartButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.jigdo_buttonInfo), _("Restart download and processing of " ".jigdo - the .jigdo data " "downloaded so far (and only it) is discarded")); } void on_jigdo_closeButton_enter(GtkButton*, gpointer) { gtk_label_set_markup(GTK_LABEL(GUI::window.jigdo_buttonInfo), _("Close this download and all its children, " "and remove them from the list below")); } void on_jigdo_button_leave(GtkButton*, gpointer) { gtk_label_set_text(GTK_LABEL(GUI::window.jigdo_buttonInfo), ""); }