diff --git a/gsmartcontrol/NEWS b/gsmartcontrol/NEWS index c6cd161..ce7d9e7 100644 --- a/gsmartcontrol/NEWS +++ b/gsmartcontrol/NEWS @@ -1,3 +1,12 @@ +Version 1.1.2, released on + +Version 1.1.1, released on 2017-09-25 + Windows: Use Adwaita GTK+ theme for systems which support Classic Windows + theme, since the default win32 GTK+ theme is broken in it; this + includes Windows 7 and Windows Server. + Statistics entry values are formatted with commas for readability. + Moved help information to website. + Version 1.1.0, released on 2017-09-07 New Statistics, Temperature Log, Error Recovery, Physical and Directory tabs. diff --git a/gsmartcontrol/TODO b/gsmartcontrol/TODO index 3466898..5dd575c 100644 --- a/gsmartcontrol/TODO +++ b/gsmartcontrol/TODO @@ -20,6 +20,8 @@ local scope destruction also works if using stack variables. TODO: +Include hi-res icon_cddvd.png and icon_hdd.png. + Don't rely on smartctl return code (2), parse the output instead. This will allow us to show the Info page. diff --git a/gsmartcontrol/configure.ac b/gsmartcontrol/configure.ac index b56e556..9a45d97 100644 --- a/gsmartcontrol/configure.ac +++ b/gsmartcontrol/configure.ac @@ -336,7 +336,7 @@ do # on separate line for portability fi if test "$RES_BASE_EXT" = "ui"; then - RES_LIBADD="$RES_LIBADD $RES_BASE_NOEXT.ui.$ac_objext" # file.ui.o or file.glade.o + RES_LIBADD="$RES_LIBADD $RES_BASE_NOEXT.ui.$ac_objext" # file.ui.o RES_TARGETS="$RES_TARGETS $RES_BASE_NOEXT.ui.cpp: $RES_FILE_CANON \"\$(top_srcdir)/file2csource.sh\" \"$RES_FILE_CANON\" \"$RES_BASE_NOEXT.ui.cpp\" \"$RES_BASE_NOEXT\"_ui diff --git a/gsmartcontrol/data/gsmartcontrol-root.in b/gsmartcontrol/data/gsmartcontrol-root.in index 5d34194..176e193 100644 --- a/gsmartcontrol/data/gsmartcontrol-root.in +++ b/gsmartcontrol/data/gsmartcontrol-root.in @@ -71,7 +71,7 @@ fi # They're basically the same, only the order is different. -# pkexec is for PolKit +# pkexec is for PolKit. # sux requires xterm to ask for the password. # xdg-su is basically like this script, except worse :) # su-to-root is a debian/ubuntu official method (although gksu is available). @@ -102,7 +102,7 @@ if [ "$GSMARTCONTROL_SU" = "" ]; then if [ "$found_su" = "" ]; then xmessage "Error launching ${prog_name}: No suitable su mechanism found. -Try installing kdesu, gnomesu, gksu, beesu or sux first."; +Try installing PolKit, kdesu, gnomesu, gksu, beesu or sux first."; exit 1; fi fi @@ -138,7 +138,7 @@ if [ "$GSMARTCONTROL_SU" != "" ]; then full_cmd="$GSMARTCONTROL_SU '$EXEC_BIN $final_args_quoted'"; elif [ "$found_su" = "pkexec" ]; then - full_cmd="pkexec --disable-internal-agent $EXEC_BIN $final_args_quoted"; + full_cmd="pkexec --disable-internal-agent $EXEC_BIN $final_args_quoted --gdk-scale='$GDK_SCALE' --gdk-dpi-scale='$GDK_DPI_SCALE'"; elif [ "$found_su" = "sux" ]; then full_cmd="xterm -e sux -c '$EXEC_BIN $final_args_quoted'"; diff --git a/gsmartcontrol/data/icon_cddvd.png b/gsmartcontrol/data/icon_cddvd.png index 4ecbd37..c11bf8a 100644 Binary files a/gsmartcontrol/data/icon_cddvd.png and b/gsmartcontrol/data/icon_cddvd.png differ diff --git a/gsmartcontrol/data/icon_hdd.png b/gsmartcontrol/data/icon_hdd.png index 1ca0a45..68351d1 100644 Binary files a/gsmartcontrol/data/icon_hdd.png and b/gsmartcontrol/data/icon_hdd.png differ diff --git a/gsmartcontrol/src/applib/app_ui_res_utils.h b/gsmartcontrol/src/applib/app_ui_res_utils.h index 8d48a21..1c9cdbb 100644 --- a/gsmartcontrol/src/applib/app_ui_res_utils.h +++ b/gsmartcontrol/src/applib/app_ui_res_utils.h @@ -35,8 +35,7 @@ /// \def APP_UI_RES_DATA_INIT(res_name) /// Use these in window class definitions to declare ui resources. /// E.g. APP_UI_RES_DATA_INIT(main_window) will search for -/// main_window.glade or main_window.ui (depending on whether -/// you're using libglade or gtkbuilder) in data file search paths. +/// main_window.ui in data file search paths. /// Or, if you're using compiled-in buffers, it will make them available. #define APP_UI_RES_DATA_INIT(res_name) \ HZ_RES_DATA_INIT_NAMED(res_name##_ui, #res_name ".ui", UIResDataBase); \ @@ -91,10 +90,10 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref, -// These allow easy attaching of glade widget signals to member functions +// These allow easy attaching of gtkbuilder widget signals to member functions /// Connect member function (callback) to signal \c signal_name on widget -/// \c ui_element, where \c ui_element is the widget's glade/gtkbuilder name. +/// \c ui_element, where \c ui_element is the widget's gtkbuilder name. #define APP_UI_RES_CONNECT(ui_element, signal_name, callback) \ if (true) { \ if (!ui_element) \ @@ -107,7 +106,7 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref, /// Connect member function (callback) with a name of \c on__ /// to signal \c signal_name on widget \c ui_element, where \c ui_element is the -/// widget's glade/gtkbuilder name. +/// widget's gtkbuilder name. #define APP_UI_RES_AUTO_CONNECT(ui_element, signal_name) \ APP_UI_RES_CONNECT(ui_element, signal_name, on_ ## ui_element ## _ ## signal_name) @@ -115,7 +114,7 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref, -/// Inherit this when using Glade-enabled windows (or any other glade-enabled objects). +/// Inherit this when using GtkBuilder-enabled windows (or any other GtkBuilder-enabled objects). /// \c Child is the child class that inherits all the functionality of having instance lifetime /// management and other benefits. /// If \c MultiInstance is false, create() will return the same instance each time. @@ -137,7 +136,7 @@ class AppUIResWidget : public WidgetType, public hz::InstanceManagersignal_delete_event().connect(sigc::mem_fun(*this, &MainWindow::on_main_window_delete)); - // signals of glade-created objects: + // signals of GtkBuilder-created objects: // Gtk::ToolButton* rescan_devices_toolbutton = 0; // APP_UI_RES_AUTO_CONNECT(rescan_devices_toolbutton, clicked); diff --git a/gsmartcontrol/src/applib/app_ui_res_utils_test.cpp b/gsmartcontrol/src/applib/app_ui_res_utils_test.cpp index 662e9fe..b1703d0 100644 --- a/gsmartcontrol/src/applib/app_ui_res_utils_test.cpp +++ b/gsmartcontrol/src/applib/app_ui_res_utils_test.cpp @@ -26,7 +26,7 @@ class AppUiResTestWindow : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(app_ui_res_test_window); diff --git a/gsmartcontrol/src/gsc_about_dialog.cpp b/gsmartcontrol/src/gsc_about_dialog.cpp index 23ea6f0..a77423b 100644 --- a/gsmartcontrol/src/gsc_about_dialog.cpp +++ b/gsmartcontrol/src/gsc_about_dialog.cpp @@ -23,7 +23,7 @@ -// glade/gtkbuilder needs this constructor +// GtkBuilder needs this constructor GscAboutDialog::GscAboutDialog(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui) : AppUIResWidget(gtkcobj, ref_ui) { diff --git a/gsmartcontrol/src/gsc_about_dialog.h b/gsmartcontrol/src/gsc_about_dialog.h index df03875..85fcf6c 100644 --- a/gsmartcontrol/src/gsc_about_dialog.h +++ b/gsmartcontrol/src/gsc_about_dialog.h @@ -24,7 +24,7 @@ class GscAboutDialog : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_about_dialog); // we need the license file to show it. @@ -35,7 +35,7 @@ class GscAboutDialog : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_add_device_window); - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscAddDeviceWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui); /// Virtual destructor diff --git a/gsmartcontrol/src/gsc_executor_log_window.h b/gsmartcontrol/src/gsc_executor_log_window.h index e88ae11..4680a98 100644 --- a/gsmartcontrol/src/gsc_executor_log_window.h +++ b/gsmartcontrol/src/gsc_executor_log_window.h @@ -27,11 +27,11 @@ class GscExecutorLogWindow : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_executor_log_window); - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscExecutorLogWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui); /// Virtual destructor diff --git a/gsmartcontrol/src/gsc_info_window.h b/gsmartcontrol/src/gsc_info_window.h index b4eb76e..6074030 100644 --- a/gsmartcontrol/src/gsc_info_window.h +++ b/gsmartcontrol/src/gsc_info_window.h @@ -27,11 +27,11 @@ class GscInfoWindow : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_info_window); - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscInfoWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui); /// Virtual destructor diff --git a/gsmartcontrol/src/gsc_init.cpp b/gsmartcontrol/src/gsc_init.cpp index f17581c..7ea42d1 100644 --- a/gsmartcontrol/src/gsc_init.cpp +++ b/gsmartcontrol/src/gsc_init.cpp @@ -210,7 +210,9 @@ namespace { arg_scan(TRUE), arg_hide_tabs(TRUE), arg_add_virtual(NULL), - arg_add_device(NULL) + arg_add_device(NULL), + arg_gdk_scale(-1), + arg_gdk_dpi_scale(-1) { } // Note: Use GLib types here: @@ -220,6 +222,8 @@ namespace { gboolean arg_hide_tabs; ///< if true, hide additional info tabs when smart is disabled. false may help debugging. gchar** arg_add_virtual; ///< load smartctl data from these files as virtual drives gchar** arg_add_device; ///< add these device files manually + gint arg_gdk_scale; ///< The value of GDK_SCALE environment variable + gint arg_gdk_dpi_scale; ///< The value of GDK_DPI_SCALE environment variable }; @@ -243,6 +247,13 @@ namespace { "Add this device to device list. The format of the device is \"::::\", where type and extra_args are optional." " This option is useful with --no-scan to list certain drives only. You can specify this option multiple times." " Example: --add-device /dev/sda --add-device /dev/twa0::3ware,2 --add-device '/dev/sdb::::-T permissive'", NULL }, +#ifndef _WIN32 + // X11-specific + { "gdk-scale", 'l', 0, G_OPTION_ARG_INT, &(args.arg_gdk_scale), + "The value of GDK_SCALE environment variable (useful when executing with pkexec)", NULL }, + { "gdk-dpi-scale", 'l', 0, G_OPTION_ARG_INT, &(args.arg_gdk_dpi_scale), + "The value of GDK_DPI_SCALE environment variable (useful when executing with pkexec)", NULL }, +#endif { NULL } }; @@ -386,10 +397,21 @@ bool app_init_and_loop(int& argc, char**& argv) << "\thide_tabs: " << args.arg_hide_tabs << "\n" << "\tscan: " << args.arg_scan << "\n" << "\targ_add_virtual: " << (load_virtuals_str.empty() ? "[empty]" : load_virtuals_str) << "\n" - << "\targ_add_device: " << (load_devices_str.empty() ? "[empty]" : load_devices_str) << "\n"); + << "\targ_add_device: " << (load_devices_str.empty() ? "[empty]" : load_devices_str) << "\n" + << "\targ_gdk_scale: " << args.arg_gdk_scale << "\n" + << "\targ_gdk_dpi_scale: " << args.arg_gdk_dpi_scale << "\n"); debug_out_dump("app", "LibDebug options:\n" << debug_get_cmd_args_dump()); +#ifndef _WIN32 + if (args.arg_gdk_scale > 0) { + hz::env_set_value("GDK_SCALE", hz::number_to_string(args.arg_gdk_scale)); + } + if (args.arg_gdk_dpi_scale > 0) { + hz::env_set_value("GDK_DPI_SCALE", hz::number_to_string(args.arg_gdk_dpi_scale)); + } +#endif + // Load config files app_init_config(); @@ -400,8 +422,8 @@ bool app_init_and_loop(int& argc, char**& argv) static const char* const gtkdomains[] = { // no atk or cairo, they don't log. libgnomevfs may be loaded by gtk file chooser. "GLib", "GModule", "GLib-GObject", "GLib-GRegex", "GLib-GIO", "GThread", - "Pango", "Gtk", "Gdk", "GdkPixbuf", "libglade", "libgnomevfs", - "glibmm", "giomm", "atkmm", "pangomm", "gdkmm", "gtkmm", "libglademm" }; + "Pango", "Gtk", "Gdk", "GdkPixbuf", "libgnomevfs", + "glibmm", "giomm", "atkmm", "pangomm", "gdkmm", "gtkmm" }; for (unsigned int i = 0; i < G_N_ELEMENTS(gtkdomains); ++i) { g_log_set_handler(gtkdomains[i], GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL diff --git a/gsmartcontrol/src/gsc_main_window.h b/gsmartcontrol/src/gsc_main_window.h index 719b474..a96b88a 100644 --- a/gsmartcontrol/src/gsc_main_window.h +++ b/gsmartcontrol/src/gsc_main_window.h @@ -34,11 +34,11 @@ class GscMainWindow : public AppUIResWidget { friend class GscMainWindowIconView; // It needs our privates - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_main_window); - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscMainWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui); /// Virtual destructor diff --git a/gsmartcontrol/src/gsc_main_window_iconview.h b/gsmartcontrol/src/gsc_main_window_iconview.h index a26afaf..f048e5d 100644 --- a/gsmartcontrol/src/gsc_main_window_iconview.h +++ b/gsmartcontrol/src/gsc_main_window_iconview.h @@ -29,7 +29,7 @@ /// The icon view of the main window (shows a drive list). -/// Note: The IconView must have a fixed icon width set (e.g. in glade file). +/// Note: The IconView must have a fixed icon width set (e.g. in .ui file). /// Otherwise, it doesn't re-compute it when clearing and adding new icons. class GscMainWindowIconView : public Gtk::IconView { public: @@ -47,7 +47,7 @@ class GscMainWindowIconView : public Gtk::IconView { }; - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscMainWindowIconView(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui) : Gtk::IconView(gtkcobj), num_icons(0), main_window(0), empty_view_message(message_none) { @@ -57,7 +57,15 @@ class GscMainWindowIconView : public Gtk::IconView { columns.add(col_description); columns.add(col_pixbuf); + +#if GTK_CHECK_VERSION(3, 10, 0) + // For high quality rendering with GDK_SCALE=2 + this->pack_start(cell_renderer_pixbuf, false); + this->set_cell_data_func(cell_renderer_pixbuf, + sigc::mem_fun(this, &GscMainWindowIconView::on_cell_data_render)); +#else this->set_pixbuf_column(col_pixbuf); +#endif columns.add(col_drive_ptr); @@ -78,18 +86,14 @@ class GscMainWindowIconView : public Gtk::IconView { // nothing } - // Try Gnome icons icons first, they are usually more consistent with Gnome desktop - // (this should work only if gnome-settings-daemon is running, so no harm on other desktops). - // The problem with stock gtk icons is that they are not available in 48x48 size, so - // confirm all sizes manually. - - if (app_gtkmm_icon_theme_has_icon(default_icon_theme, "gnome-dev-harddisk", 48)) - hd_icon = default_icon_theme->load_icon("gnome-dev-harddisk", 48, Gtk::IconLookupFlags(0)); - - if (!hd_icon && app_gtkmm_icon_theme_has_icon(default_icon_theme, "gtk-harddisk", 48)) - hd_icon = default_icon_theme->load_icon("gtk-harddisk", 48, Gtk::IconLookupFlags(0)); - - if (!hd_icon) { // still no luck, use bundled ones. + // Try XDG version first + hd_icon = default_icon_theme->load_icon("drive-harddisk", 64, get_scale_factor(), Gtk::IconLookupFlags(0)); + if (!hd_icon) { + // Before gtk 3.10 it was called gtk-harddisk. + hd_icon = default_icon_theme->load_icon("gtk-harddisk", 64, get_scale_factor(), Gtk::IconLookupFlags(0)); + } + if (!hd_icon) { + // Still no luck, use bundled ones. std::string icon_file = hz::data_file_find("icon_hdd.png"); if (!icon_file.empty()) { try { @@ -98,18 +102,14 @@ class GscMainWindowIconView : public Gtk::IconView { } } - // last resort. gtk has gtk-harddisk built-in. it may not be the right size, but what else can we do? - if (!hd_icon && default_icon_theme) - hd_icon = default_icon_theme->load_icon("gtk-harddisk", 48, Gtk::IconLookupFlags(0)); - - - if (app_gtkmm_icon_theme_has_icon(default_icon_theme, "gnome-dev-cdrom", 48)) - cddvd_icon = default_icon_theme->load_icon("gnome-dev-cdrom", 48, Gtk::IconLookupFlags(0)); - - if (!cddvd_icon && app_gtkmm_icon_theme_has_icon(default_icon_theme, "gtk-cdrom", 48)) - cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", 48, Gtk::IconLookupFlags(0)); - - if (!cddvd_icon) { // still no luck, use bundled ones. + // Try XDG version first + cddvd_icon = default_icon_theme->load_icon("media-optical", 64, get_scale_factor(), Gtk::IconLookupFlags(0)); + if (!cddvd_icon) { + // Before gtk 3.10 it was called gtk-cdrom. + cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", 64, get_scale_factor(), Gtk::IconLookupFlags(0)); + } + if (!cddvd_icon) { + // Still no luck, use bundled ones. std::string icon_file = hz::data_file_find("icon_cddvd.png"); if (!icon_file.empty()) { try { @@ -118,10 +118,6 @@ class GscMainWindowIconView : public Gtk::IconView { } } - if (!cddvd_icon && default_icon_theme) - cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", 48, Gtk::IconLookupFlags(0)); - - this->signal_item_activated().connect(sigc::mem_fun(*this, &self_type::on_iconview_item_activated) ); @@ -189,6 +185,35 @@ class GscMainWindowIconView : public Gtk::IconView { +#if GTK_CHECK_VERSION(3, 10, 0) + /// Cell data renderer (needed for high quality icons in GDK_SCALE=2). + /// We have to use Cairo surfaces, because pixbufs are scaled by GtkIconView. + void on_cell_data_render(const Gtk::TreeModel::const_iterator& iter) + { + Gtk::TreeRow row = *iter; + Glib::RefPtr pixbuf = row[col_pixbuf]; + + // Gtkmm property_surface() doesn't work, so use plain C. + // https://bugzilla.gnome.org/show_bug.cgi?id=788513 + // Also, Gtkmm doesn't have gdk_cairo_surface_create_from_pixbuf() wrapper. + // https://bugzilla.gnome.org/show_bug.cgi?id=788533 + +// Cairo::Format format = Cairo::FORMAT_ARGB32; +// if (pixbuf->get_n_channels() == 3) { +// format = Cairo::FORMAT_RGB24; +// } +// Cairo::RefPtr surface = get_window()->create_similar_image_surface( +// format, pixbuf->get_width(), pixbuf->get_height(), get_scale_factor()); +// cell_renderer_pixbuf.property_surface().set_value(surface); + + // gdk_cairo_surface_create_from_pixbuf() (and create_similar_image_surface()) from gtk 3.10. + cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(pixbuf->gobj(), get_scale_factor(), get_window()->gobj()); + g_object_set(G_OBJECT(cell_renderer_pixbuf.gobj()), "surface", surface, NULL); + cairo_surface_destroy(surface); + } +#endif + + /// Add a drive entry to the icon view void add_entry(StorageDeviceRefPtr drive, bool scroll_to_it = false) { @@ -241,13 +266,19 @@ class GscMainWindowIconView : public Gtk::IconView { // it needs this space to be symmetric (why?); std::string name; // = "" + drive->get_device_with_type() + " \n"; + Glib::ustring drive_letters = Glib::Markup::escape_text(drive->format_drive_letters()); + if (drive_letters.empty()) { + drive_letters = "not mounted"; + } // note: if this wraps, it becomes left-aligned in gtk <= 2.10. name += (drive->get_model_name().empty() ? Glib::ustring("Unknown model") : Glib::Markup::escape_text(drive->get_model_name())); if (rconfig::get_data("gui/icons_show_device_name")) { if (!drive->get_is_virtual()) { name += "\n" + Glib::Markup::escape_text(drive->get_device_with_type()); - name += " (" + Glib::Markup::escape_text(drive->format_drive_letters()) + ")"; + #ifdef _WIN32 + name += " (" + drive_letters + ")"; + #endif } else if (!drive->get_virtual_filename().empty()) { name += "\n" + Glib::Markup::escape_text(drive->get_virtual_filename()); } @@ -274,9 +305,11 @@ class GscMainWindowIconView : public Gtk::IconView { } else { tooltip_strs.push_back("Device: " + Glib::Markup::escape_text(drive->get_device_with_type()) + ""); } - if (!drive->format_drive_letters().empty()) { - tooltip_strs.push_back("Drive letters: " + Glib::Markup::escape_text(drive->format_drive_letters()) + ""); - } + + #ifdef _WIN32 + tooltip_strs.push_back("Drive letters: " + drive_letters + ""); + #endif + if (!drive->get_serial_number().empty()) { tooltip_strs.push_back("Serial number: " + Glib::Markup::escape_text(drive->get_serial_number()) + ""); } @@ -302,22 +335,24 @@ class GscMainWindowIconView : public Gtk::IconView { StorageProperty health_prop = drive->get_health_property(); if (health_prop.warning != StorageProperty::warning_none && health_prop.generic_name == "overall_health") { - icon = icon->copy(); // work on a copy - if (icon->get_colorspace() == Gdk::COLORSPACE_RGB && icon->get_bits_per_sample() == 8) { - int n_channels = icon->get_n_channels(); - int icon_width = icon->get_width(); - int icon_height = icon->get_height(); - int rowstride = icon->get_rowstride(); - guint8* pixels = icon->get_pixels(); + if (icon) { + icon = icon->copy(); // work on a copy + if (icon->get_colorspace() == Gdk::COLORSPACE_RGB && icon->get_bits_per_sample() == 8) { + int n_channels = icon->get_n_channels(); + int icon_width = icon->get_width(); + int icon_height = icon->get_height(); + int rowstride = icon->get_rowstride(); + guint8* pixels = icon->get_pixels(); - guint8* p = 0; - for (int y = 0; y < icon_height; ++y) { - for (int x = 0; x < icon_width; ++x) { - p = pixels + y * rowstride + x * n_channels; - uint8_t avg = static_cast(std::floor((p[0] * 0.30) + (p[1] * 0.59) + (p[2] * 0.11) + 0.001 + 0.5)); - p[0] = avg; // R - p[1] = 0; // G - p[2] = 0; // B + guint8* p = 0; + for (int y = 0; y < icon_height; ++y) { + for (int x = 0; x < icon_width; ++x) { + p = pixels + y * rowstride + x * n_channels; + uint8_t avg = static_cast(std::floor((p[0] * 0.30) + (p[1] * 0.59) + (p[2] * 0.11) + 0.001 + 0.5)); + p[0] = avg; // R + p[1] = 0; // G + p[2] = 0; // B + } } } } @@ -507,6 +542,7 @@ class GscMainWindowIconView : public Gtk::IconView { private: Gtk::TreeModel::ColumnRecord columns; ///< Model columns + Gtk::CellRendererPixbuf cell_renderer_pixbuf; ///< Cell renderer for icons. Gtk::TreeModelColumn col_name; ///< Model column Gtk::TreeModelColumn col_description; ///< Model column diff --git a/gsmartcontrol/src/gsc_preferences_window.cpp b/gsmartcontrol/src/gsc_preferences_window.cpp index 45c004e..729a6ec 100644 --- a/gsmartcontrol/src/gsc_preferences_window.cpp +++ b/gsmartcontrol/src/gsc_preferences_window.cpp @@ -33,7 +33,7 @@ class GscPreferencesDeviceOptionsTreeView : public Gtk::TreeView { typedef GscPreferencesDeviceOptionsTreeView self_type; ///< Self type, needed for CONNECT_VIRTUAL - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscPreferencesDeviceOptionsTreeView(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui) : Gtk::TreeView(gtkcobj), preferences_window(0) { diff --git a/gsmartcontrol/src/gsc_preferences_window.h b/gsmartcontrol/src/gsc_preferences_window.h index 3533f76..0ca4af6 100644 --- a/gsmartcontrol/src/gsc_preferences_window.h +++ b/gsmartcontrol/src/gsc_preferences_window.h @@ -29,11 +29,11 @@ class GscMainWindow; // declared in gsc_main_window.h class GscPreferencesWindow : public AppUIResWidget { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_preferences_window); - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscPreferencesWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui); /// Virtual destructor diff --git a/gsmartcontrol/src/gsc_text_window.h b/gsmartcontrol/src/gsc_text_window.h index b9da5e2..6dc2d8d 100644 --- a/gsmartcontrol/src/gsc_text_window.h +++ b/gsmartcontrol/src/gsc_text_window.h @@ -38,14 +38,14 @@ template class GscTextWindow : public AppUIResWidget, InstanceSwitch::multi_instance> { public: - // name of glade/ui file without a .glade/.ui extension and quotes + // name of ui file without a .ui extension and quotes APP_UI_RES_DATA_INIT(gsc_text_window); - /// Self type, needed for glade, not inherited from parent because of templates + /// Self type, needed for GtkBuilder, not inherited from parent because of templates typedef GscTextWindow self_type; - /// Constructor, gtkbuilder/glade needs this. + /// Constructor, GtkBuilder needs this. GscTextWindow(typename Gtk::Window::BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui) : AppUIResWidget, InstanceSwitch::multi_instance>(gtkcobj, ref_ui) { diff --git a/gsmartcontrol/src/hz/res_data.h b/gsmartcontrol/src/hz/res_data.h index b72dc9a..0fb9762 100644 --- a/gsmartcontrol/src/hz/res_data.h +++ b/gsmartcontrol/src/hz/res_data.h @@ -34,7 +34,7 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1). // Compiled-in buffers: /// Declare that we have a binary chunk res_name. -/// (You may use this e.g. with glade xml contents, putting it into your window class). +/// (You may use this e.g. with GtkBuilder xml contents, putting it into your window class). #define HZ_RES_DATA_COMPILED_INIT_NAMED(res_name, dummy, class_name) \ struct class_name { \ class_name() \ diff --git a/gsmartcontrol/src/res/Makefile.am b/gsmartcontrol/src/res/Makefile.am index 8aa4e85..916a99d 100644 --- a/gsmartcontrol/src/res/Makefile.am +++ b/gsmartcontrol/src/res/Makefile.am @@ -1,9 +1,9 @@ # Disable implicit suffix rules for these extensions. -# The problem is that make sees the .glade.cpp or .ui.cpp files -# with their .glade prerequisites, and decides to rebuild the -# (already existing) .glade files by using .glade.cpp files. -# Implicit rules are to blame, so disable them for .glade. +# The problem is that make sees the .ui.cpp files +# with their .ui prerequisites, and decides to rebuild the +# (already existing) .ui files by using .ui.cpp files. +# Implicit rules are to blame, so disable them for .ui. SUFFIXES = .ui .txt AM_CPPFLAGS = diff --git a/gsmartcontrol/src/res/gsc_main_window.ui b/gsmartcontrol/src/res/gsc_main_window.ui index a6994c7..8f09944 100644 --- a/gsmartcontrol/src/res/gsc_main_window.ui +++ b/gsmartcontrol/src/res/gsc_main_window.ui @@ -136,9 +136,9 @@ True GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 10 - 130 + 250 3 - 8 + 20 5