Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / filebrowser.cc
blob12b7a940b190c18c2272a37fa717afd4fe026c16
1 /*
2 * This file is part of RawTherapee.
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
19 #include <filebrowser.h>
20 #include <glibmm.h>
21 #include <options.h>
22 #include <multilangmgr.h>
23 #include <clipboard.h>
24 #include <profilestore.h>
25 #include <procparamchangers.h>
27 FileBrowser::FileBrowser ()
28 : tbl(NULL) {
30 fbih = new FileBrowserIdleHelper;
31 fbih->fbrowser = this;
32 fbih->destroyed = false;
33 fbih->pending = 0;
35 profileStore.parseProfiles ();
37 signal_style_changed().connect( sigc::mem_fun(*this, &FileBrowser::styleChanged) );
39 int p = 0;
40 pmenu = new Gtk::Menu ();
41 pmenu->attach (*(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p+1); p++;
42 pmenu->attach (*(develop = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESS"))), 0, 1, p, p+1); p++;
43 pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
44 pmenu->attach (*(rank[0] = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNRANK"))), 0, 1, p, p+1); p++;
45 pmenu->attach (*(rank[1] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK1"))), 0, 1, p, p+1); p++;
46 pmenu->attach (*(rank[2] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK2"))), 0, 1, p, p+1); p++;
47 pmenu->attach (*(rank[3] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK3"))), 0, 1, p, p+1); p++;
48 pmenu->attach (*(rank[4] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK4"))), 0, 1, p, p+1); p++;
49 pmenu->attach (*(rank[5] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK5"))), 0, 1, p, p+1); p++;
50 pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
51 pmenu->attach (*(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++;
52 pmenu->attach (*(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++;
53 pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
54 pmenu->attach (*(rename = new Gtk::MenuItem (M("FILEBROWSER_POPUPRENAME"))), 0, 1, p, p+1); p++;
55 pmenu->attach (*(remove = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVE"))), 0, 1, p, p+1); p++;
56 pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
57 pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++;
58 pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
59 pmenu->attach (*(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++;
60 pmenu->attach (*(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++;
61 pmenu->attach (*(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++;
62 pmenu->attach (*(applyprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE"))), 0, 1, p, p+1); p++;
63 pmenu->attach (*(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p+1); p++;
64 pmenu->show_all ();
66 pmaccelgroup = Gtk::AccelGroup::create ();
67 pmenu->set_accel_group (pmaccelgroup);
68 selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
69 trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
70 untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
71 develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Q, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
72 copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
73 pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
74 partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
76 profmenu = new Gtk::Menu ();
78 open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open));
79 for (int i=0; i<6; i++)
80 rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i]));
81 trash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), trash));
82 untrash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), untrash));
83 develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop));
84 rename->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rename));
85 remove->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), remove));
86 selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall));
87 copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof));
88 pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof));
89 partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof));
90 applyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applyprof));
91 clearprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearprof));
94 void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) {
96 trash->set_sensitive (false);
97 untrash->set_sensitive (false);
98 for (int i=0; i<selected.size(); i++)
99 if (((FileBrowserEntry*)selected[i])->thumbnail->getStage()==1) {
100 untrash->set_sensitive (true);
101 break;
103 for (int i=0; i<selected.size(); i++)
104 if (((FileBrowserEntry*)selected[i])->thumbnail->getStage()==0) {
105 trash->set_sensitive (true);
106 break;
109 pasteprof->set_sensitive (clipboard.hasProcParams());
110 partpasteprof->set_sensitive (clipboard.hasProcParams());
111 copyprof->set_sensitive (selected.size()==1);
112 clearprof->set_sensitive (selected.size()>0);
114 int p = 0;
115 Gtk::Menu* applmenu = Gtk::manage (new Gtk::Menu ());
116 std::vector<Glib::ustring> profnames = profileStore.getProfileNames ();
117 for (int i=0; i<profnames.size(); i++) {
118 Gtk::MenuItem* mi = Gtk::manage (new Gtk::MenuItem (profnames[i]));
119 applmenu->attach (*mi, 0, 1, p, p+1); p++;
120 mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyMenuItemActivated), profnames[i]));
121 mi->show ();
123 applyprof->set_submenu (*applmenu);
125 pmenu->popup (3, this->eventTime);
128 void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry) {
130 if (tbl && entry) {
131 std::vector<Thumbnail*> entries;
132 entries.push_back (((FileBrowserEntry*)entry)->thumbnail);
133 tbl->openRequested (entries);
137 struct addparams {
138 FileBrowserIdleHelper* fbih;
139 FileBrowserEntry* entry;
142 int addfl (void* data) {
144 addparams* ap = (addparams*) data;
145 FileBrowserIdleHelper* fbih = ap->fbih;
147 gdk_threads_enter();
149 if (fbih->destroyed) {
150 if (fbih->pending == 1)
151 delete fbih;
152 else
153 fbih->pending--;
154 delete ap->entry;
155 delete ap;
156 gdk_threads_leave ();
157 return 0;
160 ap->fbih->fbrowser->addEntry_ (ap->entry);
161 delete ap;
162 fbih->pending--;
163 gdk_threads_leave();
164 return 0;
167 void FileBrowser::addEntry (FileBrowserEntry* entry) {
169 fbih->pending++;
170 entry->setParent (this);
171 addparams* ap = new addparams;
172 ap->fbih = fbih;
173 ap->entry = entry;
174 g_idle_add (addfl, ap);
177 void FileBrowser::addEntry_ (FileBrowserEntry* entry) {
179 entry->selected = false;
180 entry->drawable = false;
181 entry->framed = editedFiles.find (entry->filename)!=editedFiles.end();
183 // add button set to the thumbbrowserentry
184 entry->addButtonSet (new FileThumbnailButtonSet (entry));
185 entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank());
186 entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()==1);
187 entry->getThumbButtonSet()->setButtonListener (this);
188 entry->resize (options.thumbSize);
190 // find place in abc order
191 std::vector<ThumbBrowserEntryBase*>::iterator i = fd.begin();
192 while (i!=fd.end() && *entry < *((FileBrowserEntry*)*i))
193 i++;
195 fd.insert (i, entry);
197 initEntry (entry);
198 redraw ();
201 FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) {
203 for (std::vector<ThumbBrowserEntryBase*>::iterator i=fd.begin(); i!=fd.end(); i++)
204 if ((*i)->filename==fname) {
205 ThumbBrowserEntryBase* entry = *i;
206 entry->selected = false;
207 fd.erase (i);
208 std::vector<ThumbBrowserEntryBase*>::iterator j = std::find (selected.begin(), selected.end(), entry);
209 if (j!=selected.end()) {
210 selected.erase (j);
211 notifySelectionListener ();
213 if (lastClicked==entry)
214 lastClicked = NULL;
215 redraw ();
216 return (FileBrowserEntry*)entry;
218 return NULL;
221 FileBrowserEntry* FileBrowser::findEntry (const Glib::ustring& fname) {
223 for (std::vector<ThumbBrowserEntryBase*>::iterator i=fd.begin(); i!=fd.end(); i++)
224 if ((*i)->filename==fname)
225 return (FileBrowserEntry*)*i;
226 return NULL;
229 void FileBrowser::close () {
230 if (fbih->pending)
231 fbih->destroyed = true;
232 else
233 delete fbih;
235 fbih = new FileBrowserIdleHelper;
236 fbih->fbrowser = this;
237 fbih->destroyed = false;
238 fbih->pending = 0;
240 for (int i=0; i<fd.size(); i++)
241 delete fd[i];
242 fd.clear ();
243 selected.clear ();
244 notifySelectionListener ();
245 lastClicked = NULL;
246 for (int i=0; i<fd.size(); i++)
247 ((FileBrowserEntry*)fd[i])->thumbnail->decreaseRef ();
250 void FileBrowser::menuItemActivated (Gtk::MenuItem* m) {
252 std::vector<FileBrowserEntry*> mselected;
253 for (int i=0; i<selected.size(); i++)
254 mselected.push_back ((FileBrowserEntry*)selected[i]);
256 if (!tbl || (m!=selall && mselected.size()==0) )
257 return;
259 for (int i=0; i<6; i++)
260 if (m==rank[i]) {
261 rankingRequested (mselected, i);
262 return;
264 if (m==open) {
265 std::vector<Thumbnail*> entries;
266 for (int i=0; i<mselected.size(); i++)
267 entries.push_back (mselected[i]->thumbnail);
268 tbl->openRequested (entries);
270 else if (m==remove)
271 tbl->deleteRequested (mselected);
272 else if (m==trash)
273 toTrashRequested (mselected);
274 else if (m==untrash)
275 fromTrashRequested (mselected);
276 else if (m==develop)
277 tbl->developRequested (mselected);
278 else if (m==rename)
279 tbl->renameRequested (mselected);
280 else if (m==selall) {
281 lastClicked = NULL;
282 selected.clear ();
283 for (int i=0; i<fd.size(); i++)
284 if (checkFilter (fd[i])) {
285 fd[i]->selected = true;
286 selected.push_back (fd[i]);
288 queue_draw ();
289 notifySelectionListener ();
291 else if (m==copyprof)
292 copyProfile ();
293 else if (m==pasteprof)
294 pasteProfile ();
295 else if (m==partpasteprof)
296 partPasteProfile ();
297 else if (m==clearprof) {
298 for (int i=0; i<mselected.size(); i++)
299 mselected[i]->thumbnail->clearProcParams (FILEBROWSER);
300 queue_draw ();
304 void FileBrowser::copyProfile () {
306 if (selected.size()==1)
307 clipboard.setProcParams (((FileBrowserEntry*)selected[0])->thumbnail->getProcParams());
310 void FileBrowser::pasteProfile () {
312 std::vector<FileBrowserEntry*> mselected;
313 for (int i=0; i<selected.size(); i++)
314 mselected.push_back ((FileBrowserEntry*)selected[i]);
316 if (!tbl || mselected.size()==0)
317 return;
319 for (int i=0; i<mselected.size(); i++)
320 mselected[i]->thumbnail->setProcParams (clipboard.getProcParams(), FILEBROWSER);
322 queue_draw ();
325 void FileBrowser::partPasteProfile () {
327 std::vector<FileBrowserEntry*> mselected;
328 for (int i=0; i<selected.size(); i++)
329 mselected.push_back ((FileBrowserEntry*)selected[i]);
331 if (!tbl || mselected.size()==0)
332 return;
334 if (partialPasteDlg.run ()) {
336 for (int i=0; i<mselected.size(); i++) {
337 rtengine::procparams::ProcParams params = mselected[i]->thumbnail->getProcParams ();
338 partialPasteDlg.applyPaste (&params, &clipboard.getProcParams());
339 mselected[i]->thumbnail->setProcParams (params, FILEBROWSER);
342 queue_draw ();
344 partialPasteDlg.hide ();
347 bool FileBrowser::keyPressed (GdkEventKey* event) {
349 if ((event->keyval==GDK_C || event->keyval==GDK_c) && event->state & GDK_CONTROL_MASK) {
350 copyProfile ();
351 return true;
353 else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) {
354 pasteProfile ();
355 return true;
357 else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) {
358 partPasteProfile ();
359 return true;
361 else if (event->keyval==GDK_Delete && !(event->state & GDK_SHIFT_MASK)) {
362 menuItemActivated (trash);
363 return true;
365 else if (event->keyval==GDK_Delete && event->state & GDK_SHIFT_MASK) {
366 menuItemActivated (untrash);
367 return true;
369 else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && event->state & GDK_CONTROL_MASK) {
370 menuItemActivated (develop);
371 return true;
373 else if ((event->keyval==GDK_A || event->keyval==GDK_a) && event->state & GDK_CONTROL_MASK) {
374 menuItemActivated (selall);
375 return true;
378 return false;
381 void FileBrowser::applyMenuItemActivated (Glib::ustring ppname) {
383 rtengine::procparams::ProcParams* pparams = profileStore.getProfile (ppname);
384 if (pparams && selected.size()>0) {
385 for (int i=0; i<selected.size(); i++)
386 ((FileBrowserEntry*)selected[i])->thumbnail->setProcParams (*pparams, FILEBROWSER);
387 queue_draw ();
391 void FileBrowser::applyFilter (const BrowserFilter& filter) {
393 this->filter = filter;
395 // remove items not complying the filter from the selection
396 bool selchanged = false;
397 for (int i=0; i<fd.size(); i++)
398 if (fd[i]->selected && !checkFilter (fd[i])) {
399 fd[i]->selected = false;
400 std::vector<ThumbBrowserEntryBase*>::iterator j = std::find (selected.begin(), selected.end(), fd[i]);
401 selected.erase (j);
402 if (lastClicked==fd[i])
403 lastClicked = NULL;
404 selchanged = true;
406 if (selchanged)
407 notifySelectionListener ();
408 redraw ();
411 bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry complies filter
413 FileBrowserEntry* entry = (FileBrowserEntry*)entryb;
414 // return false if basic filter settings are not satisfied
415 if (filter.showRanked[entry->thumbnail->getRank()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash))
416 return false;
418 // check exif filter
419 const CacheImageData* cfs = entry->thumbnail->getCacheImageData();
420 double tol = 0.01;
421 double tol2 = 1e-8;
423 if (!filter.exifFilterEnabled)
424 return true;
426 if (!cfs->exifValid)
427 return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0)
428 && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0);
430 return
431 (!filter.exifFilter.filterShutter || (rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom-tol2 && rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo+tol2))
432 && (!filter.exifFilter.filterFNumber || (rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) >= filter.exifFilter.fnumberFrom-tol2 && rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) <= filter.exifFilter.fnumberTo+tol2))
433 && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom-tol && cfs->focalLen <= filter.exifFilter.focalTo+tol))
434 && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo))
435 && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0)
436 && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0);
439 void FileBrowser::toTrashRequested (std::vector<FileBrowserEntry*> tbe) {
441 for (int i=0; i<tbe.size(); i++) {
442 if (tbe[i]->thumbnail->getStage()==1)
443 continue;
444 tbe[i]->thumbnail->setStage (1);
445 if (tbe[i]->getThumbButtonSet()) {
446 tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
447 tbe[i]->getThumbButtonSet()->setInTrash (true);
450 applyFilter (filter);
453 void FileBrowser::fromTrashRequested (std::vector<FileBrowserEntry*> tbe) {
455 for (int i=0; i<tbe.size(); i++) {
456 if (tbe[i]->thumbnail->getStage()==0)
457 continue;
458 tbe[i]->thumbnail->setStage (0);
459 if (tbe[i]->getThumbButtonSet()) {
460 tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
461 tbe[i]->getThumbButtonSet()->setInTrash (false);
464 applyFilter (filter);
467 void FileBrowser::rankingRequested (std::vector<FileBrowserEntry*> tbe, int rank) {
469 for (int i=0; i<tbe.size(); i++) {
470 tbe[i]->thumbnail->setRank (rank);
471 if (tbe[i]->getThumbButtonSet())
472 tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
474 applyFilter (filter);
477 void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionData) {
479 if (actionCode>=0 && actionCode<=5) { // rank
480 std::vector<FileBrowserEntry*> tbe;
481 tbe.push_back ((FileBrowserEntry*)actionData);
482 rankingRequested (tbe, actionCode);
484 else if (actionCode==6 && tbl) { // to processin queue
485 std::vector<FileBrowserEntry*> tbe;
486 tbe.push_back ((FileBrowserEntry*)actionData);
487 tbl->developRequested (tbe);
489 else if (actionCode==7) { // to trash / undelete
490 std::vector<FileBrowserEntry*> tbe;
491 FileBrowserEntry* entry = (FileBrowserEntry*)actionData;
492 tbe.push_back (entry);
493 if (entry->thumbnail->getStage()==0)
494 toTrashRequested (tbe);
495 else
496 fromTrashRequested (tbe);
500 void FileBrowser::openNextImage () {
502 if (fd.size()>0) {
503 for (int i=fd.size()-1; i>=0; i--)
504 if (editedFiles.find (fd[i]->filename)!=editedFiles.end())
505 if (i<fd.size()-1 && tbl) {
506 std::vector<Thumbnail*> entries;
507 entries.push_back (((FileBrowserEntry*)fd[i+1])->thumbnail);
508 tbl->openRequested (entries);
509 return;
511 if (tbl) {
512 std::vector<Thumbnail*> entries;
513 entries.push_back (((FileBrowserEntry*)fd[0])->thumbnail);
514 tbl->openRequested (entries);
519 void FileBrowser::openPrevImage () {
521 if (fd.size()>0) {
522 for (int i=0; i<fd.size(); i++)
523 if (editedFiles.find (fd[i]->filename)!=editedFiles.end())
524 if (i>0 && tbl) {
525 std::vector<Thumbnail*> entries;
526 entries.push_back (((FileBrowserEntry*)fd[i-1])->thumbnail);
527 tbl->openRequested (entries);
528 return;
530 if (tbl) {
531 std::vector<Thumbnail*> entries;
532 entries.push_back (((FileBrowserEntry*)fd[fd.size()-1])->thumbnail);
533 tbl->openRequested (entries);
538 int redrawtb (void* data) {
540 ((FileBrowser*)data)->_thumbRearrangementNeeded ();
541 return 0;
544 void FileBrowser::_thumbRearrangementNeeded () {
546 refreshThumbImages ();
549 void FileBrowser::thumbRearrangementNeeded () {
551 g_idle_add (redrawtb, this);
553 void FileBrowser::selectionChanged () {
555 notifySelectionListener ();
558 void FileBrowser::notifySelectionListener () {
560 if (tbl) {
561 std::vector<Thumbnail*> thm;
562 for (int i=0; i<selected.size(); i++)
563 thm.push_back (((FileBrowserEntry*)selected[i])->thumbnail);
564 tbl->selectionChanged (thm);
568 void FileBrowser::redrawNeeded (ThumbBrowserEntryBase* entry) {
570 if (entry->insideWindow (0, 0, internal.get_width(), internal.get_height())) {
571 if (!internal.isDirty ()) {
572 internal.setDirty ();
573 internal.queue_draw ();
578 void FileBrowser::redrawNeeded (LWButton* button) {
580 queue_draw ();