all repos — tint2 @ cf9ddbd9fbc476a18ce888cc9bdc8ea5089849ec

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

cleanup tested code

git-svn-id: http://tint2.googlecode.com/svn/trunk@147 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
lorthiois@bbsoft.fr lorthiois@bbsoft.fr@121b4492-b84c-0410-8b4c-0d4edfb3f3cc
commit

cf9ddbd9fbc476a18ce888cc9bdc8ea5089849ec

parent

3926a0026cd1087c1ab5880dcf6ecfe3b44d6c16

6 files changed, 121 insertions(+), 1030 deletions(-)

jump to
A src/tint2conf/main.c

@@ -0,0 +1,121 @@

+/************************************************************************** +* +* Tint2conf +* +* Copyright (C) 2009 Thierry lorthiois (lorthiois@bbsoft.fr) +* +* This program 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. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**************************************************************************/ + +#include <stdio.h> +#include <locale.h> +#include <gtk/gtk.h> +#include <glib.h> +#include <glib/gstdio.h> +#include <glib/gi18n.h> + + +// gcc -Wall -g main.c -o tint2conf `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0 --libs gthread-2.0` +// need GTK+-2.4 ou plus + +#define LONG_VERSION_STRING "0.2" + +static GtkUIManager *myUIManager = NULL; + +static const char *fallback_ui_file = + "<ui>" + " <menubar name='MenuBar'>" + " <menu action='ThemeMenu'>" + " </menu>" + " </menubar>" + " <toolbar name='ToolBar'>" + " <toolitem action='ViewRefreshAll'/>" + " <separator/>" + " <toolitem action='ThemeProperties'/>" + " <toolitem action='ViewApply'/>" + " </toolbar>" + "</ui>"; + + +static void about( GtkWindow * parent ) +{ + const char *authors[] = { "Thierry Lorthiois", "Christian Ruppert (Build system)", NULL }; + + const char *website_url = "http://code.google.com/p/tint2/"; + + gtk_show_about_dialog( parent, "name", g_get_application_name( ), + "comments", _( "Theming tool for tint2 panel" ), + "version", LONG_VERSION_STRING, + "website", website_url, "website-label", website_url, + "copyright", _( "Copyright 2009 Thierry Lorthiois" ), + "logo-icon-name", "", +#ifdef SHOW_LICENSE + "license", LICENSE, "wrap-license", TRUE, +#endif + "authors", authors, + /* Translators: translate "translator-credits" as + your name to have it appear in the credits in the "About" + dialog */ + "translator-credits", _( "translator-credits" ), + NULL ); +} + + +static void destroy( GtkWidget *widget, gpointer data ) +{ + gtk_main_quit (); +} + + +int main (int argc, char ** argv) +{ +/* + bindtextdomain( domain, LOCALEDIR ); + bind_textdomain_codeset( domain, "UTF-8" ); + textdomain( domain ); +*/ + + setlocale( LC_ALL, "" ); + gtk_init (&argc, &argv); + g_thread_init( NULL ); + + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "Tint2 theme"); + gtk_window_set_default_size(GTK_WINDOW(window), 600, 350); + + // define GUI action + myUIManager = gtk_ui_manager_new ( ); + GtkActionGroup *action_group; + + //actions_init ( myUIManager, cbdata ); + gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL ); + gtk_ui_manager_ensure_update ( myUIManager ); + + // XDG specification + char *dir = g_build_filename (g_get_user_config_dir(), "tint2", NULL); + if (!g_file_test (dir, G_FILE_TEST_IS_DIR)) g_mkdir(dir, 0777); + //window.view.set_dir(dir); + //window.view.load_dir(); + g_free(dir); + + g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); + // rig up idle/thread routines + //Glib::Thread::create(sigc::mem_fun(window.view, &Thumbview::load_cache_images), true); + //Glib::Thread::create(sigc::mem_fun(window.view, &Thumbview::create_cache_images), true); + + gtk_widget_show (window); + gtk_main (); + + return 0; +} +
D src/tint2conf/main.cpp

@@ -1,54 +0,0 @@

-/************************************************************************** -* -* Tint2conf -* -* Copyright (C) 2009 Thierry lorthiois (lorthiois@bbsoft.fr) -* -* This program 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. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -**************************************************************************/ - -#include <string> -#include <stdio.h> -#include <gtkmm.h> -#include <glib.h> - -#include "mainwin.h" - - -// g++ `pkg-config --libs --cflags gtkmm-2.4 --libs gthread-2.0` -o tint2conf main.cpp mainwin.cpp thumbview.cpp - -int main (int argc, char ** argv) -{ - // set up i18n - //bindtextdomain(PACKAGE, LOCALEDIR); - //bind_textdomain_codeset(PACKAGE, "UTF-8"); - //textdomain(PACKAGE); - - Gtk::Main kit(argc, argv); - Glib::thread_init(); - - MainWin window; - - window.view.set_dir(""); - window.view.load_dir(); - - // rig up idle/thread routines - Glib::Thread::create(sigc::mem_fun(window.view, &Thumbview::load_cache_images), true); - Glib::Thread::create(sigc::mem_fun(window.view, &Thumbview::create_cache_images), true); - - //Shows the window and returns when it is closed. - Gtk::Main::run(window); - - return 0; -} -
D src/tint2conf/mainwin.cpp

@@ -1,140 +0,0 @@

- -#include <gtkmm/stock.h> -#include <iostream> -#include "mainwin.h" - - -MainWin::MainWin() -{ - set_title("Tint2 config"); - set_default_size(600, 350); - - add(m_Box); // put a MenuBar at the top of the box and other stuff below it. - - //Create actions for menus and toolbars: - m_refActionGroup = Gtk::ActionGroup::create(); - - //File menu: - m_refActionGroup->add(Gtk::Action::create("FileMenu", "File")); - //Sub-menu. - m_refActionGroup->add(Gtk::Action::create("FileOpen", Gtk::Stock::OPEN, "_Open", "Open config file"), sigc::mem_fun(*this, &MainWin::on_menu_file_new_generic)); - m_refActionGroup->add(Gtk::Action::create("FileSaveAs", Gtk::Stock::SAVE_AS, "_Save As", "Save config as"), sigc::mem_fun(*this, &MainWin::on_menu_file_new_generic)); - m_refActionGroup->add(Gtk::Action::create("FileRefreshAll", Gtk::Stock::REFRESH, "_Refresh all", "Refresh all config file"), sigc::mem_fun(*this, &MainWin::on_menu_file_new_generic)); - m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &MainWin::on_menu_file_quit)); - - //Edit menu: - m_refActionGroup->add(Gtk::Action::create("EditMenu", "Edit")); - m_refActionGroup->add(Gtk::Action::create("EditProperties", Gtk::Stock::PROPERTIES, "_Properties...", "Show properties"), sigc::mem_fun(*this, &MainWin::on_menu_others)); - m_refActionGroup->add(Gtk::Action::create("EditRename", "_Rename...", "Rename current config"), sigc::mem_fun(*this, &MainWin::on_menu_others)); - m_refActionGroup->add(Gtk::Action::create("EditDelete", Gtk::Stock::DELETE), sigc::mem_fun(*this, &MainWin::on_menu_others)); - m_refActionGroup->add(Gtk::Action::create("EditApply", Gtk::Stock::APPLY, "_Apply", "Apply current config"), sigc::mem_fun(*this, &MainWin::on_menu_others)); - m_refActionGroup->add(Gtk::Action::create("EditRefresh", Gtk::Stock::REFRESH), sigc::mem_fun(*this, &MainWin::on_menu_others)); - - //Help menu: - m_refActionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); - m_refActionGroup->add( Gtk::Action::create("About", Gtk::Stock::ABOUT), sigc::mem_fun(*this, &MainWin::on_menu_about) ); - - m_refUIManager = Gtk::UIManager::create(); - m_refUIManager->insert_action_group(m_refActionGroup); - - add_accel_group(m_refUIManager->get_accel_group()); - - //Layout the actions in a menubar and toolbar: - Glib::ustring ui_info = - "<ui>" - " <menubar name='MenuBar'>" - " <menu action='FileMenu'>" - " <menuitem action='FileOpen'/>" - " <menuitem action='FileSaveAs'/>" - " <separator/>" - " <menuitem action='FileRefreshAll'/>" - " <separator/>" - " <menuitem action='FileQuit'/>" - " </menu>" - " <menu action='EditMenu'>" - " <menuitem action='EditProperties'/>" - " <menuitem action='EditRename'/>" - " <separator/>" - " <menuitem action='EditDelete'/>" - " <separator/>" - " <menuitem action='EditRefresh'/>" - " </menu>" - " <menu action='HelpMenu'>" - " <menuitem action='About'/>" - " </menu>" - " </menubar>" - " <toolbar name='ToolBar'>" - " <toolitem action='FileRefreshAll'/>" - " <separator/>" - " <toolitem action='EditProperties'/>" - " <toolitem action='EditApply'/>" - " </toolbar>" - "</ui>"; - - #ifdef GLIBMM_EXCEPTIONS_ENABLED - try - { - m_refUIManager->add_ui_from_string(ui_info); - } - catch(const Glib::Error& ex) - { - std::cerr << "building menus failed: " << ex.what(); - } - #else - std::auto_ptr<Glib::Error> ex; - m_refUIManager->add_ui_from_string(ui_info, ex); - if(ex.get()) - { - std::cerr << "building menus failed: " << ex->what(); - } - #endif //GLIBMM_EXCEPTIONS_ENABLED - - //Get the menubar and toolbar widgets, and add them to a container widget: - Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar"); - if(pMenubar) - m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK); - - Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ; - if(pToolbar) - m_Box.pack_start(*pToolbar, Gtk::PACK_SHRINK); - - - m_Box.add(view); - - show_all_children(); -} - -MainWin::~MainWin() -{ -} - - -void MainWin::on_menu_file_quit() -{ - hide(); -} - - -void MainWin::on_menu_file_new_generic() -{ - std::cout << "A File|New menu item was selected." << std::endl; -} - - -void MainWin::on_menu_others() -{ - std::cout << "A menu item was selected." << std::endl; -} - - -void MainWin::on_menu_about() -{ - Glib::ustring message = "tint2conf " + Glib::ustring(VERSION); - Gtk::MessageDialog dialog(*this, message); - - dialog.set_title("About tint2conf"); - dialog.set_secondary_text("Config tool for tint2.\n\nCopyright (C) 2009 Thierry lorthiois. \nRefer to source code from Nitrogen\nby Dave Foster & Javeed Shaikh."); - - dialog.run(); -} -
D src/tint2conf/mainwin.h

@@ -1,33 +0,0 @@

-#ifndef TINT2CONF_MAINWIN_H -#define TINT2CONF_MAINWIN_H - -#include <gtkmm.h> -#include "thumbview.h" - -#define VERSION "0.2" - - -class MainWin : public Gtk::Window -{ -public: - MainWin(); - virtual ~MainWin(); - - Thumbview view; -protected: - //Signal handlers: - void on_menu_file_new_generic(); - void on_menu_file_quit(); - void on_menu_others(); - void on_menu_about(); - - //Child widgets: - Gtk::VBox m_Box; - - Glib::RefPtr<Gtk::UIManager> m_refUIManager; - Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup; - Glib::RefPtr<Gtk::RadioAction> m_refChoiceOne, m_refChoiceTwo; -}; - -#endif -
D src/tint2conf/thumbview.cpp

@@ -1,641 +0,0 @@

-/* - -This file is from Nitrogen, an X11 background setter. -Copyright (C) 2006 Dave Foster & Javeed Shaikh - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ - -//#include "md5.h" -#include <glib/gstdio.h> -#include <png.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <iostream> -#include "thumbview.h" -//#include "Config.h" -//#include "Util.h" -//#include "gcs-i18n.h" - -/** - * Returns the last modified time of a file. - * @param file The name of the file to get the modified time for. - */ -static time_t get_file_mtime(std::string file) { - struct stat buf; - if (stat(file.c_str(), &buf) == -1) return 0; // error - return buf.st_mtime; -} - -/** - * Returns the value of the "tEXt::Thumb::MTime" key for fd.o style thumbs. - * @param pixbuf The pixbuf of the fd.o thumbnail. - */ -static time_t get_fdo_thumbnail_mtime(Glib::RefPtr<Gdk::Pixbuf> pixbuf) { - std::string mtime_str = pixbuf->get_option("tEXt::Thumb::MTime"); - std::stringstream stream(mtime_str); - time_t mtime = 0; - stream >> mtime; - return mtime; -} - -void DelayLoadingStore::get_value_vfunc (const iterator& iter, int column, Glib::ValueBase& value) const -{ - g_async_queue_ref(aqueue_loadthumbs); - Gtk::ListStore::get_value_vfunc(iter, column, value); - - Gtk::TreeModel::Row row = *iter; - if (column == 0) - { - Glib::Value< Glib::RefPtr<Gdk::Pixbuf> > base; - Gtk::ListStore::get_value_vfunc(iter, column, base); - - Glib::RefPtr<Gdk::Pixbuf> thumb = base.get(); - - if (thumb == thumbview->loading_image && !row[thumbview->record.LoadingThumb]) - { - TreePair* tp = new TreePair(); - tp->file = row[thumbview->record.Filename]; - tp->iter = iter; - - row[thumbview->record.LoadingThumb] = true; - - //Util::program_log("Custom model: planning on loading %s\n", tp->file.c_str()); - - g_async_queue_push(aqueue_loadthumbs, (gpointer)tp); - } - } - g_async_queue_unref(aqueue_loadthumbs); -} - -/** - * Constructor, sets up gtk stuff, inits data and queues - */ -Thumbview::Thumbview() : dir("") { - set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); - set_shadow_type (Gtk::SHADOW_IN); - - // load map of setbgs (need this for add_file) - load_map_setbgs(); - - // make our async queues - this->aqueue_loadthumbs = g_async_queue_new(); - this->aqueue_createthumbs = g_async_queue_new(); - this->aqueue_donethumbs = g_async_queue_new(); - - // create store - store = DelayLoadingStore::create (record); - store->set_queue(aqueue_loadthumbs); - store->set_thumbview(this); - - // setup view - view.set_model (store); - view.set_headers_visible (FALSE); - view.set_fixed_height_mode (TRUE); - view.set_rules_hint (TRUE); - - // set cell renderer proprties - rend.property_ellipsize () = Pango::ELLIPSIZE_END; - rend.set_property ("ellipsize", Pango::ELLIPSIZE_END); - rend.property_weight () = Pango::WEIGHT_BOLD; - - rend_img.set_fixed_size(105, 82); - - // make treeviewcolumns - this->col_thumb = new Gtk::TreeViewColumn("thumbnail", this->rend_img); - this->col_desc = new Gtk::TreeViewColumn("description", this->rend); - - col_thumb->add_attribute (rend_img, "pixbuf", record.Thumbnail); - col_thumb->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); - col_thumb->set_fixed_width(105); - col_desc->add_attribute (rend, "markup", record.Description); - col_desc->set_sort_column (record.Filename); - col_desc->set_sort_indicator (true); - col_desc->set_sort_order (Gtk::SORT_ASCENDING); - col_desc->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); - - view.append_column (*col_thumb); - view.append_column (*col_desc); - - // enable search - view.set_search_column (record.Description); - view.set_search_equal_func (sigc::mem_fun (this, &Thumbview::search_compare)); - - // load loading image, which not all themes seem to provide - try { - this->loading_image = Gtk::IconTheme::get_default()->load_icon("image-loading", 64, Gtk::ICON_LOOKUP_FORCE_SVG); - } catch (Gtk::IconThemeError e) {} - - // init dispatcher - this->dispatch_thumb.connect(sigc::mem_fun(this, &Thumbview::handle_dispatch_thumb)); - - col_desc->set_expand (); - - add (view); - - view.show (); - show (); -} - -/** - * Destructor - */ -Thumbview::~Thumbview() { - g_async_queue_unref(this->aqueue_loadthumbs); - g_async_queue_unref(this->aqueue_createthumbs); - g_async_queue_unref(this->aqueue_donethumbs); -} - -/** - * Adds the given file to the tree view and pushes it onto the thumbnail - * creation queue. - * - * @param filename The name of the file to add. - * - */ -void Thumbview::add_file(std::string filename) { - Gtk::Window *window = dynamic_cast<Gtk::Window*>(get_toplevel()); - Gtk::TreeModel::iterator iter = this->store->append (); - Gtk::TreeModel::Row row = *iter; - Glib::RefPtr<Gdk::Pixbuf> thumb = this->loading_image; - row[record.Thumbnail] = thumb; - row[record.Filename] = filename; - row[record.Description] = Glib::ustring(filename, filename.rfind ("/")+1); - - for (std::map<Glib::ustring, Glib::ustring>::iterator i = map_setbgs.begin(); i!=map_setbgs.end(); i++) - { - if (filename == (*i).second) - { - row[record.CurBGOnDisp] = (*i).first; -// row[record.Description] = Util::make_current_set_string(window, filename, (*i).first); - } - } - - // for modified time - row[record.Time] = get_file_mtime(filename); - -// Util::program_log("add_file(): Adding file %s\n", filename.c_str()); - - // push it on the thumb queue -// TreePair *tp = new TreePair(); -// tp->file = filename; -// tp->iter = iter; - -// queue_thumbs.push(tp); -} - - -/** - * Opens the internal directory and starts reading files into the async queue. - */ -void Thumbview::load_dir(std::string dir) { - if (!dir.length()) dir = this->dir; - - std::queue<Glib::ustring> subdirs; - Glib::Dir *dirhandle; - - // push the initial dir back onto subdirs - subdirs.push(dir); - - // loop it - while ( ! subdirs.empty() ) { - - // pop first - Glib::ustring curdir = subdirs.front(); - subdirs.pop(); - - try { - dirhandle = new Glib::Dir(curdir); -// Util::program_log("load_dir(): Opening dir %s\n", curdir.c_str()); - - } catch (Glib::FileError e) { - std::cerr << "Could not open dir" << " " << this->dir << ": " << e.what() << "\n"; - continue; - } - -#ifdef USE_INOTIFY - - // check if we're already monitoring this dir. - if (watches.find(curdir) == watches.end()) { - // this dir was successfully opened. monitor it for changes with inotify. - // the Watch will be cleaned up automatically if the dir is deleted. - Inotify::Watch * watch = Inotify::Watch::create(curdir); - if (watch) { - // no error occurred. - - // emitted when a file is deleted in this dir. - watch->signal_deleted.connect(sigc::mem_fun(this, - &Thumbview::file_deleted_callback)); - // emitted when a file is modified or created in this dir. - watch->signal_write_closed.connect(sigc::mem_fun(this, - &Thumbview::file_changed_callback)); - // two signals that are emitted when a file is renamed in this dir. - // the best way to handle this IMO is to remove the file upon receiving - // 'moved_from', and then to add the file upon receiving 'moved_to'. - watch->signal_moved_from.connect(sigc::mem_fun(this, - &Thumbview::file_deleted_callback)); - watch->signal_moved_to.connect(sigc::mem_fun(this, - &Thumbview::file_changed_callback)); - watch->signal_created.connect(sigc::mem_fun(this, - &Thumbview::file_created_callback)); - - watches[curdir] = watch; - } - } - -#endif - - for (Glib::Dir::iterator i = dirhandle->begin(); i != dirhandle->end(); i++) { - Glib::ustring fullstr = curdir + Glib::ustring("/"); - try { - fullstr += /*Glib::filename_to_utf8(*/*i;//); - } catch (Glib::ConvertError& error) { - std::cerr << "Invalid UTF-8 encountered. Skipping file" << " " << *i << std::endl; - continue; - } - - if ( Glib::file_test(fullstr, Glib::FILE_TEST_IS_DIR) ) - { -// if ( Config::get_instance()->get_recurse() ) -// subdirs.push(fullstr); - } - else { - if ( this->is_image(fullstr) ) { - add_file(fullstr); - } - } - } - - delete dirhandle; - } -} - -/** - * Tests the file to see if it is an image - * TODO: come up with less sux way of doing it than extension - * - * @param file The filename to test - * @return If its an image or not - */ -bool Thumbview::is_image(std::string file) { - if (file.find (".jpg") != std::string::npos || - file.find (".JPG") != std::string::npos || - file.find (".jpeg") != std::string::npos || - file.find (".JPEG") != std::string::npos ) - return true; - - return false; -} - -/** - * Determines the full path to a cache file. Does all creation of dirs. - * TODO: should throw exception if we cannot create the dirs! - * - * @param file The file to convert, calls cache_name on it - * @return The full path to - */ -Glib::ustring Thumbview::cache_file(Glib::ustring file) { - - Glib::ustring urifile = Glib::filename_to_uri(file); -/* - // compute md5 of file's uri - md5_state_t state; - md5_byte_t digest[16]; - md5_init(&state); - md5_append(&state, (const md5_byte_t *)urifile.c_str(), strlen(urifile.c_str())); - md5_finish(&state, digest); - - char *buf = new char[3]; - char *full = new char[33]; - full[0] = '\0'; - - for (int di = 0; di < 16; ++di) { - sprintf(buf, "%02x", digest[di]); - strcat(full, buf); - } - - Glib::ustring md5file = Glib::ustring(full) + Glib::ustring(".png"); - delete [] buf; - delete [] full; - - // build dir paths - Glib::ustring halfref = Glib::build_filename(Glib::get_home_dir(),".thumbnails/"); - halfref = Glib::build_filename(halfref, "normal/"); - - if ( !Glib::file_test(halfref, Glib::FILE_TEST_EXISTS) ) - if ( g_mkdir_with_parents(halfref.c_str(), 0700) == -1) - // TODO: exception - return "FAIL"; - - // add and return - return Glib::build_filename(halfref, md5file); -*/ - return urifile; -} - -/** - * Creates cache images that show up in its queue. - */ -void Thumbview::load_cache_images() -{ - g_async_queue_ref(this->aqueue_loadthumbs); - g_async_queue_ref(this->aqueue_donethumbs); - - while(1) - { - // remove first item (blocks until an item occurs) - TreePair *p = (TreePair*)g_async_queue_pop(this->aqueue_loadthumbs); - - Glib::ustring file = p->file; - Glib::ustring cachefile = this->cache_file(file); - - // branch to see if we need to load or create cache file - if ( !Glib::file_test(cachefile, Glib::FILE_TEST_EXISTS) ) { - g_async_queue_push(this->aqueue_createthumbs,(gpointer)p); - } else { - // load thumb - Glib::RefPtr<Gdk::Pixbuf> pb = Gdk::Pixbuf::create_from_file(this->cache_file(file)); - - // resize if we need to - if (pb->get_width() > 100 || pb->get_height() > 80) - { - int pbwidth = pb->get_width(); - int pbheight = pb->get_height(); - float ratio = (float)pbwidth / (float)pbheight; - - int newwidth, newheight; - - if (abs(100 - pbwidth) > abs(80 - pbheight)) - { - // cap to vertical - newheight = 80; - newwidth = newheight * ratio; - } - else - { - // cap to horiz - newwidth = 100; - newheight = newwidth / ratio; - } - - pb = pb->scale_simple(newwidth, newheight, Gdk::INTERP_NEAREST); - } - - if (get_fdo_thumbnail_mtime(pb) < get_file_mtime(file)) { - // the thumbnail is old. we need to make a new one. - pb.clear(); - g_async_queue_push(this->aqueue_createthumbs,(gpointer)p); - } else { - // display it - TreePair *sendp = new TreePair(); - sendp->file = file; - sendp->iter = p->iter; - sendp->thumb = pb; - - g_async_queue_push(this->aqueue_donethumbs, (gpointer)sendp); - - this->dispatch_thumb.emit(); - - delete p; - } - } - } - - g_async_queue_unref(this->aqueue_loadthumbs); - g_async_queue_unref(this->aqueue_donethumbs); - throw Glib::Thread::Exit(); -} - -/** - * Thread function to create thumbnail cache images for those that do not exist. - */ -void Thumbview::create_cache_images() -{ - Glib::RefPtr<Gdk::Pixbuf> thumb; - - g_async_queue_ref(this->aqueue_createthumbs); - g_async_queue_ref(this->aqueue_donethumbs); - - // always work! - while (1) { - - // remove first item (blocks when no items occur) - TreePair *p = (TreePair*)g_async_queue_pop(this->aqueue_createthumbs); - - // get filenames - Glib::ustring file = p->file; - Glib::ustring cachefile = this->cache_file(file); - -// Util::program_log("create_cache_images(): Caching file %s\n", file.c_str()); - - // open image - try { - thumb = Gdk::Pixbuf::create_from_file(file); - } catch (...) { - // forget it, move on - delete p; - continue; - } - - // eliminate zero heights (due to really tiny images :/) - int height = (int)(100*((float)thumb->get_height()/(float)thumb->get_width())); - if (!height) height = 1; - - // create thumb - thumb = thumb->scale_simple(100, height, Gdk::INTERP_TILES); - - // create required fd.o png tags - std::list<Glib::ustring> opts, vals; - opts.push_back(Glib::ustring("tEXt::Thumb::URI")); - vals.push_back(Glib::filename_to_uri(file)); - - time_t mtime = get_file_mtime(file); - - char *bufout = new char[20]; - sprintf(bufout, "%d", mtime); - - opts.push_back(Glib::ustring("tEXt::Thumb::MTime")); - vals.push_back(Glib::ustring(bufout)); - - delete [] bufout; - - thumb->save(cachefile, "png", opts, vals); - - // send it to the display - TreePair *sendp = new TreePair(); - sendp->file = file; - sendp->iter = p->iter; - sendp->thumb = thumb; - g_async_queue_push(this->aqueue_donethumbs, (gpointer)sendp); - - // emit dispatcher - this->dispatch_thumb.emit(); - - delete p; - } - - g_async_queue_unref(this->aqueue_createthumbs); - g_async_queue_unref(this->aqueue_donethumbs); - throw Glib::Thread::Exit(); -} - -void Thumbview::handle_dispatch_thumb() { - g_async_queue_ref(this->aqueue_donethumbs); - - TreePair *donep = (TreePair*)g_async_queue_pop(this->aqueue_donethumbs); - this->update_thumbnail(donep->file, donep->iter, donep->thumb); - delete donep; - - g_async_queue_unref(this->aqueue_donethumbs); -} - -/** - * Updates the treeview to show the passed in thumbnail. - * - */ -void Thumbview::update_thumbnail(Glib::ustring file, Gtk::TreeModel::iterator iter, Glib::RefPtr<Gdk::Pixbuf> pb) -{ - Gtk::TreeModel::Row row = *iter; - row[record.Thumbnail] = pb; - // desc - //row[record.Description] = Glib::ustring(file, file.rfind("/")+1); - - // emit a changed signal - store->row_changed(store->get_path(iter), iter); -} - -/** - * Used by GTK to see whether or not an iterator matches a search string. - */ -bool Thumbview::search_compare (const Glib::RefPtr<Gtk::TreeModel>& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) { - Glib::ustring target = (*iter)[record.Description]; - if (target.find (key) != Glib::ustring::npos) { - return false; - } - return true; -} - -/** - * Sets the sort mode. This tells the view how it should sort backgrounds. - */ -void Thumbview::set_sort_mode (Thumbview::SortMode mode) { - switch (mode) { - case SORT_ALPHA: - store->set_sort_column (record.Description, Gtk::SORT_ASCENDING); - break; - case SORT_RALPHA: - store->set_sort_column (record.Description, Gtk::SORT_DESCENDING); - break; - case SORT_TIME: - store->set_sort_column (record.Time, Gtk::SORT_ASCENDING); - break; - case SORT_RTIME: - store->set_sort_column (record.Time, Gtk::SORT_DESCENDING); - break; - } -} - -/** - * Loads the map of displays and their set bgs. Used to indicate which - * files are currently set as a background. - */ -void Thumbview::load_map_setbgs() -{ - map_setbgs.clear(); - - std::vector<Glib::ustring> vecgroups; - bool ret = false; -// bool ret = Config::get_instance()->get_bg_groups(vecgroups); - if (!ret) - return; - - for (std::vector<Glib::ustring>::iterator i = vecgroups.begin(); i!=vecgroups.end(); i++) - { - Glib::ustring file; -// SetBG::SetMode mode; - Gdk::Color bgcolor; - -// ret = Config::get_instance()->get_bg(*i, file, mode, bgcolor); - if (!ret) - { - std::cerr << "(load_map_setbgs) Could not get background stored info for " << *i << "\n"; - return; - } - - map_setbgs[*i] = file; - } -} - -#ifdef USE_INOTIFY - -/** - * Called when a file in a directory being monitored by inotify is deleted. - * Removes the file from the tree view. - * - * @param filename The name of the file to remove. - */ -void Thumbview::file_deleted_callback(std::string filename) { - if (watches.find(filename) != watches.end()) { - watches.erase(filename); - return; - } - Gtk::TreeIter iter; - Gtk::TreeModel::Children children = store->children(); - for (iter = children.begin(); iter != children.end(); iter++) { - Glib::ustring this_filename = (*iter)[record.Filename]; - if (this_filename == filename) { - // remove this iter. - store->erase(iter); - break; - } - } -} - -/** - * Called when a file in a directory being monitored by inotify is modified - * or a new file is created. Adds the file to the tree view. - * - * @param filename The name of the file modified or created. - */ -void Thumbview::file_changed_callback(std::string filename) { - // first remove the old instance of this file. - file_deleted_callback(filename); - if ( Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) ) { - // this is a directory; use load_dir() to set us up the bomb. - load_dir(filename); - } else if (is_image(filename)) { - // this is a file. - add_file(filename); - } - // restart the idle function - //Glib::signal_idle().connect(sigc::mem_fun(this, &Thumbview::load_cache_images)); -} - -/** - * Called when a new file or directory is created in a directory being - * monitored. Discards the event for non-directories, because - * file_changed_callback will be called for those. - * - * @param filename The name of the file modified or created. - */ -void Thumbview::file_created_callback(std::string filename) { - if ( Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) ) { - file_changed_callback(filename); - } -} - -#endif
D src/tint2conf/thumbview.h

@@ -1,162 +0,0 @@

-/* - -This file is from Nitrogen, an X11 background setter. -Copyright (C) 2006 Dave Foster & Javeed Shaikh - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ - -#include <queue> -#include <errno.h> -#include <gtkmm.h> - -#ifdef USE_INOTIFY -//#include "Inotify.h" -#endif - -struct TreePair { - Glib::ustring file; - Gtk::TreeModel::iterator iter; - Glib::RefPtr<Gdk::Pixbuf> thumb; -}; - -class Thumbview; - -class DelayLoadingStore : public Gtk::ListStore -{ - public: - static Glib::RefPtr<DelayLoadingStore> create(const Gtk::TreeModelColumnRecord& columns) - { - return Glib::RefPtr<DelayLoadingStore>(new DelayLoadingStore(columns)); - } - - protected: - DelayLoadingStore() : Gtk::ListStore() {} - DelayLoadingStore(const Gtk::TreeModelColumnRecord& columns) : Gtk::ListStore(columns) {} - - protected: - virtual void get_value_vfunc (const iterator& iter, int column, Glib::ValueBase& value) const; - - public: - void set_queue(GAsyncQueue *queue) { aqueue_loadthumbs = queue; } - void set_thumbview(Thumbview *view) { thumbview = view; } - - protected: - GAsyncQueue *aqueue_loadthumbs; - Thumbview *thumbview; - - -}; - -///////////////////////////////////////////////////////////////////////////// - -/** - * Column record for the Thumbview store. - */ -class ThumbviewRecord : public Gtk::TreeModelColumnRecord -{ - public: - ThumbviewRecord() - { - add(Thumbnail); - add(Description); - add(Filename); - add(Time); - add(LoadingThumb); - add(CurBGOnDisp); - } - - Gtk::TreeModelColumn<Glib::ustring> Filename; - Gtk::TreeModelColumn<Glib::ustring> Description; - Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > Thumbnail; - Gtk::TreeModelColumn<time_t> Time; - Gtk::TreeModelColumn<bool> LoadingThumb; - Gtk::TreeModelColumn<Glib::ustring> CurBGOnDisp; -}; - - -///////////////////////////////////////////////////////////////////////////// - -class Thumbview : public Gtk::ScrolledWindow { - public: - Thumbview (); - ~Thumbview (); - - typedef enum { - SORT_ALPHA, - SORT_RALPHA, - SORT_TIME, - SORT_RTIME - } SortMode; - - void set_dir(std::string indir) { this->dir = indir; } - - Glib::RefPtr<DelayLoadingStore> store; - Gtk::TreeView view; - ThumbviewRecord record; - - // dispatcher - Glib::Dispatcher dispatch_thumb; - - // thread/idle funcs - void load_cache_images(); - void create_cache_images(); - void load_dir(std::string dir = ""); - - void set_sort_mode (SortMode mode); - // search compare function - bool search_compare (const Glib::RefPtr<Gtk::TreeModel>& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter); - - // loading image - Glib::RefPtr<Gdk::Pixbuf> loading_image; - - // "cache" of config - maps displays to full filenames - std::map<Glib::ustring, Glib::ustring> map_setbgs; - void load_map_setbgs(); - - protected: - -#ifdef USE_INOTIFY - void file_deleted_callback(std::string filename); - void file_changed_callback(std::string filename); - void file_created_callback(std::string filename); - std::map<std::string, Inotify::Watch*> watches; -#endif - - void add_file(std::string filename); - void handle_dispatch_thumb(); - - Gtk::TreeViewColumn *col_thumb; - Gtk::TreeViewColumn *col_desc; - - Gtk::CellRendererPixbuf rend_img; - Gtk::CellRendererText rend; - - // utility functions - bool is_image(std::string file); - Glib::ustring cache_file(Glib::ustring file); - void update_thumbnail(Glib::ustring file, Gtk::TreeModel::iterator iter, Glib::RefPtr<Gdk::Pixbuf> pb); - - // base dir - // TODO: remove when we get a proper db - std::string dir; - - // load thumbnail queue - GAsyncQueue* aqueue_loadthumbs; - GAsyncQueue* aqueue_createthumbs; - GAsyncQueue* aqueue_donethumbs; - -};