reduce number of file system accesses to load icon files, Issue 2816

This commit is contained in:
Ingo 2015-06-24 21:08:28 +02:00
parent 44f26d43a2
commit 4ab63d8e65
2 changed files with 39 additions and 37 deletions

View File

@ -20,64 +20,67 @@
#include "rtimage.h" #include "rtimage.h"
#include "../rtengine/safegtk.h" #include "../rtengine/safegtk.h"
#include "../rtengine/safekeyfile.h"
extern Glib::ustring argv0; extern Glib::ustring argv0;
extern Options options; extern Options options;
std::vector<Glib::ustring> imagesPaths; std::vector<Glib::ustring> imagesPaths;
std::vector<RTImage*> imagesList; // List of images in order to live update them on theme switch std::map<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> > pixBufMap; // List of image buffers in order to live update them on theme switch and to avoid a lot of file accesses
/* /*
* RTImage is a derived class of Gtk::Image, in order to handle theme related iconsets * RTImage is a derived class of Gtk::Image, in order to handle theme related iconsets
*/ */
RTImage::RTImage(Glib::ustring fileName, Glib::ustring rtlFileName) : Gtk::Image() { RTImage::RTImage(Glib::ustring fileName, Glib::ustring rtlFileName) : Gtk::Image() {
Glib::ustring path; Glib::ustring mapKey;
if (rtlFileName.length()) { if (rtlFileName.length()) {
const Gtk::TextDirection dir = get_direction(); if (get_direction() == Gtk::TEXT_DIR_RTL) {
if (dir == Gtk::TEXT_DIR_RTL) mapKey = rtlFileName;
path = findIconAbsolutePath(rtlFileName); } else {
else mapKey = fileName;
path = findIconAbsolutePath(fileName); }
} else {
mapKey = fileName;
} }
else
path = findIconAbsolutePath(fileName); std::map<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> >::iterator it;
it = pixBufMap.find(mapKey);
set(path); if (it != pixBufMap.end()) {
imagesList.push_back(this); set(it->second);
} else {
Glib::RefPtr<Gdk::Pixbuf> tempPixPuf = Gdk::Pixbuf::create_from_file(findIconAbsolutePath(mapKey));
pixBufMap.insert(std::pair<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> >(mapKey, tempPixPuf));
set(tempPixPuf);
}
} }
RTImage::~RTImage() { void RTImage::updateImages() {
// Remove the image from the global images list std::map<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> >::iterator it;
std::vector<RTImage*>::iterator i = std::find (imagesList.begin(), imagesList.end(), this); for (it=pixBufMap.begin(); it!=pixBufMap.end(); ++it) {
if (i!=imagesList.end()) Glib::ustring fullPath = findIconAbsolutePath(it->first);
imagesList.erase(i); it->second = Gdk::Pixbuf::create_from_file(fullPath);
}
} }
void RTImage::updateImages() { // DONE (was TODO: Maybe this could be optimized: in order to avoid looking up for an icon file in the filesystem on each popupmenu selection, maybe we could find a way to copy the image data from another RTImage)
for (unsigned int i=0; i<imagesList.size(); i++) {
Glib::ustring oldPath = imagesList[i]->property_file();
Glib::ustring fileName = Glib::path_get_basename(oldPath);
imagesList[i]->clear();
Glib::ustring fullPath = findIconAbsolutePath(fileName);
imagesList[i]->set(fullPath);
}
}
// TODO: Maybe this could be optimized: in order to avoid looking up for an icon file in the filesystem on each popupmenu selection, maybe we could find a way to copy the image data from another RTImage
void RTImage::changeImage(Glib::ustring &newImage) { void RTImage::changeImage(Glib::ustring &newImage) {
clear(); clear();
Glib::ustring fullPath = findIconAbsolutePath(newImage); std::map<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> >::iterator it;
set(fullPath); it = pixBufMap.find(newImage);
if (it != pixBufMap.end()) {
set(it->second);
} else {
Glib::ustring fullPath = findIconAbsolutePath(newImage);
Glib::RefPtr<Gdk::Pixbuf> tempPixPuf = Gdk::Pixbuf::create_from_file(fullPath);
pixBufMap.insert(std::pair<Glib::ustring,Glib::RefPtr<Gdk::Pixbuf> >(newImage, tempPixPuf));
set(tempPixPuf);
}
} }
Glib::ustring RTImage::findIconAbsolutePath(const Glib::ustring &iconFName) { Glib::ustring RTImage::findIconAbsolutePath(const Glib::ustring &iconFName) {
Glib::ustring path; Glib::ustring path;
for (unsigned int i=0; i<imagesPaths.size(); i++) { for (unsigned int i=0; i<imagesPaths.size(); i++) {
path = Glib::build_filename(imagesPaths[i], iconFName); path = Glib::build_filename(imagesPaths[i], iconFName);
//printf("\"%s\" \n", path.c_str());
if (safe_file_test(path, Glib::FILE_TEST_EXISTS)) { if (safe_file_test(path, Glib::FILE_TEST_EXISTS)) {
//printf("Found!\n");
return path; return path;
} }
} }

View File

@ -25,7 +25,6 @@
class RTImage : public Gtk::Image { class RTImage : public Gtk::Image {
public: public:
RTImage(Glib::ustring fileName, Glib::ustring rtlFileName = ""); RTImage(Glib::ustring fileName, Glib::ustring rtlFileName = "");
~RTImage();
static void setPaths(Options &opt); static void setPaths(Options &opt);
static void updateImages(); static void updateImages();
void changeImage(Glib::ustring &newImage); void changeImage(Glib::ustring &newImage);