New feature: search by filename and file browser toolbar optimization (issue 788)

This patch adds "Find" entry box to the toolbar to perform case-insensitive search by part of image filename.
Also, there is a new option in preferences to display File Browser toolbar as single row or not. This also solves issue with lower resolution displays.
This commit is contained in:
Michael Ezra 2011-06-22 17:23:08 -04:00
parent 05fb2fb1c0
commit 86d600a8b3
13 changed files with 148 additions and 32 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
rtdata/images/x_10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -59,7 +59,10 @@ FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thum
FILEBROWSER_AUTODARKFRAME;Auto dark frame
FILEBROWSER_AUTOFLATFIELD;Auto flat field
FILEBROWSER_BROWSEPATHBUTTONHINT;Click to browse to the chosen path
FILEBROWSER_BROWSEPATHHINT;Type path to browse (<b>Ctrl-o</b> set focus,<b>Ctrl-Enter</b> to browse in File Browser);\nPath shortcuts: <b>~</b> - user's home directory, <b>!</b> - user's pictures directory
FILEBROWSER_BROWSEPATHHINT;Type path to browse\n<b>Ctrl-o</b> set focus\n<b>Enter</b>, <b>Ctrl-Enter</b> (in File Browser) to browse;\nPath shortcuts:\n <b>~</b> - user's home directory\n <b>!</b> - user's pictures directory
FILEBROWSER_QUERYBUTTONHINT;Clear the Find query
FILEBROWSER_QUERYHINT;Type a part of filename to search by \n<b>Ctrl-f</b> set focus (in File Browser);\n<b>Enter</b> to find
FILEBROWSER_QUERYLABEL; Find:
FILEBROWSER_CACHE;Cache
FILEBROWSER_CACHECLEARFROMFULL;Clear from cache - full
FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial
@ -121,7 +124,7 @@ FILEBROWSER_SHOWCOLORLABEL2HINT;Show images labeled Yelow <b>Alt-2</b>
FILEBROWSER_SHOWCOLORLABEL3HINT;Show images labeled Green <b>Alt-3</b>
FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue <b>Alt-4</b>
FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple <b>Alt-5</b>
FILEBROWSER_SHOWDIRHINT;Show all images in the directory (clear all filters) <b>D</b>
FILEBROWSER_SHOWDIRHINT;Clear all filters <b>D</b>
FILEBROWSER_SHOWEXIFINFO;Show EXIF info <b>i</b>
FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue
FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star <b>1</b>
@ -568,6 +571,7 @@ PREFERENCES_EDITORCMDLINE;Other command line
PREFERENCES_EDITORLAYOUT;Editor Layout
PREFERENCES_EXTERNALEDITOR;External editor
PREFERENCES_FBROWSEROPTS;File Browser Options
PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low res display)
PREFERENCES_FILEFORMAT;File format
PREFERENCES_FLATFIELD;Flat Field
PREFERENCES_FLATFIELDFOUND;Found

View File

@ -20,6 +20,7 @@
#define _BROWSERFILTER_
#include <exiffiltersettings.h>
#include <glibmm.h>
class BrowserFilter {
@ -29,7 +30,10 @@ class BrowserFilter {
bool showTrash;
bool showNotTrash;
bool showEdited[2];
Glib::ustring queryString;
Glib::ustring queryFileName;
bool exifFilterEnabled;
ExifFilterSettings exifFilter;

View File

@ -693,6 +693,19 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry
if (filter.showRanked[entry->thumbnail->getRank()]==false || filter.showCLabeled[entry->thumbnail->getColorLabel()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash))
return false;
// return false is query is not satisfied
if (filter.queryFileName.size()>0){
// check if image's FileName contains queryFileName (case insensitive)
// TODO should we provide case-sensitive search option via preferences?
Glib::ustring FileName;
FileName = Glib::path_get_basename (entry->thumbnail->getFileName());
FileName = FileName.uppercase();
//printf("FileBrowser::checkFilter FileName = '%s'; find() result= %i \n",FileName.c_str(), FileName.find(filter.queryFileName.uppercase()));
if (FileName.find(filter.queryFileName.uppercase())==-1)
return false;
}
// check exif filter
const CacheImageData* cfs = entry->thumbnail->getCacheImageData();
double tol = 0.01;

View File

@ -69,6 +69,51 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) :
emptyT->show ();
trashButtonBox->show ();
//initialize hbToolBar1
Gtk::HBox* hbToolBar1 = Gtk::manage(new Gtk::HBox ());
//setup BrowsePath
iRefreshWhite = new Gtk::Image(argv0+"/images/refresh_white.png");
iRefreshRed = new Gtk::Image(argv0+"/images/refresh_red.png");
BrowsePath = Gtk::manage(new Gtk::Entry ());
BrowsePath->set_width_chars (50);
BrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHHINT"));
Gtk::HBox* hbBrowsePath = Gtk::manage(new Gtk::HBox ());
buttonBrowsePath = Gtk::manage(new Gtk::Button ());
buttonBrowsePath->set_image (*iRefreshWhite);
buttonBrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHBUTTONHINT"));
buttonBrowsePath->set_relief (Gtk::RELIEF_NONE);
buttonBrowsePath->signal_clicked().connect( sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed) );
hbBrowsePath->pack_start (*BrowsePath, Gtk::PACK_EXPAND_WIDGET,0);
hbBrowsePath->pack_start (*buttonBrowsePath,Gtk::PACK_SHRINK, 0);
hbToolBar1->pack_start (*hbBrowsePath, Gtk::PACK_EXPAND_WIDGET,0);
BrowsePath->signal_activate().connect (sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed)); //respond to the Enter key
//setup Query
iQueryClear = new Gtk::Image(argv0+"/images/x_10.png");
Gtk::Label* labelQuery = Gtk::manage(new Gtk::Label(M("FILEBROWSER_QUERYLABEL")));
Query = Gtk::manage(new Gtk::Entry ()); // cannot use Gtk::manage here as FileCatalog::getFilter will fail on Query->get_text()
Query->set_text("");
Query->set_width_chars (20); // TODO !!! add this value to options?
Query->set_tooltip_markup (M("FILEBROWSER_QUERYHINT"));
Gtk::HBox* hbQuery = Gtk::manage(new Gtk::HBox ());
buttonQueryClear = Gtk::manage(new Gtk::Button ());
buttonQueryClear->set_image (*iQueryClear);
buttonQueryClear->set_tooltip_markup (M("FILEBROWSER_QUERYBUTTONHINT"));
buttonQueryClear->set_relief (Gtk::RELIEF_NONE);
buttonQueryClear->signal_clicked().connect( sigc::mem_fun(*this, &FileCatalog::buttonQueryClearPressed) );
hbQuery->pack_start (*labelQuery,Gtk::PACK_SHRINK, 0);
hbQuery->pack_start (*Query,Gtk::PACK_SHRINK, 0);
hbQuery->pack_start (*buttonQueryClear,Gtk::PACK_SHRINK, 0);
hbToolBar1->pack_start (*hbQuery, Gtk::PACK_SHRINK,0);
Query->signal_activate().connect (sigc::mem_fun(*this, &FileCatalog::executeQuery)); //respond to the Enter key
// if NOT a single row toolbar
if (!options.FileBrowserToolbarSingleRow) pack_start (*hbToolBar1, Gtk::PACK_SHRINK,0);
// setup button bar
buttonBar = Gtk::manage( new Gtk::HBox () );
pack_start (*buttonBar, Gtk::PACK_SHRINK);
@ -220,33 +265,14 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) :
zoomOutButton->set_tooltip_markup (M("FILEBROWSER_ZOOMOUTHINT"));
zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK);
// add default panel
hBox = Gtk::manage( new Gtk::HBox () );
hBox->show ();
hBox->pack_end (*fileBrowser);
fileBrowser->applyFilter (getFilter());
pack_start (*hBox);
buttonBar->pack_start (*zoomBox, Gtk::PACK_SHRINK);
// add browserPath
buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK);
iRightArrow = new Gtk::Image(argv0+"/images/right.png");
iRightArrow_red = new Gtk::Image(argv0+"/images/right_red.png");
//iRightArrow = new Gtk::Image(argv0+"/images/right.png");
//iRightArrow_red = new Gtk::Image(argv0+"/images/right_red.png");
BrowsePath = new Gtk::Entry ();
BrowsePath->set_width_chars (50); // !!! add this value to options
BrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHHINT"));
Gtk::HBox* hbBrowsePath = new Gtk::HBox ();
buttonBrowsePath = new Gtk::Button ();
buttonBrowsePath->set_image (*iRightArrow);
buttonBrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHBUTTONHINT"));
buttonBrowsePath->set_relief (Gtk::RELIEF_NONE);
hbBrowsePath->pack_start (*BrowsePath);
hbBrowsePath->pack_start (*buttonBrowsePath,Gtk::PACK_SHRINK, 4);
buttonBar->pack_start (*hbBrowsePath, Gtk::PACK_EXPAND_WIDGET,4);
buttonBrowsePath->signal_clicked().connect( sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed) );
// if it IS a single row toolbar
if (options.FileBrowserToolbarSingleRow) buttonBar->pack_start (*hbToolBar1, Gtk::PACK_EXPAND_WIDGET,0);
tbRightPanel_1 = new Gtk::ToggleButton ();
iRightPanel_1_Show = new Gtk::Image(argv0+"/images/panel_to_left.png");
@ -264,6 +290,14 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) :
buttonBar->pack_end (*toolBar, Gtk::PACK_SHRINK);
buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4);
// add default panel
hBox = Gtk::manage( new Gtk::HBox () );
hBox->show ();
hBox->pack_end (*fileBrowser);
fileBrowser->applyFilter (getFilter()); // warning: can call this only after all objects used in getFilter (e.g. Query) are instantiated
//printf("FileCatalog::FileCatalog fileBrowser->applyFilter (getFilter())\n");
pack_start (*hBox);
enabled = true;
lastScrollPos = 0;
@ -287,6 +321,13 @@ FileCatalog::~FileCatalog(){
}
delete iTrashEmpty;
delete iTrashFull;
delete iRefreshWhite;
delete iRefreshRed;
delete iQueryClear;
delete iLeftPanel_1_Show;
delete iLeftPanel_1_Hide;
delete iRightPanel_1_Show;
delete iRightPanel_1_Hide;
}
bool FileCatalog::capture_event(GdkEventButton* event){
@ -366,8 +407,9 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring
addAndOpenFile (openfile);
selectedDirectory = dir->get_parse_name();
//printf("FileCatalog::dirSelected selectedDirectory = %s\n",selectedDirectory.c_str());
BrowsePath->set_text (selectedDirectory);
buttonBrowsePath->set_image (*iRightArrow);
buttonBrowsePath->set_image (*iRefreshWhite);
fileNameList = getFileList ();
for (unsigned int i=0; i<fileNameList.size(); i++) {
@ -1007,11 +1049,26 @@ BrowserFilter FileCatalog::getFilter () {
filter.exifFilter = currentEFS;
filter.exifFilterEnabled = filterPanel->isEnabled ();
}
//TODO add support for more query options. e.g by date, iso, f-number, etc
//TODO could use date:<value>;iso:<value> etc
// default will be filename
/* // this is for safe execution if getFilter is called before Query object is instantiated
Glib::ustring tempQuery;
tempQuery="";
if (Query) tempQuery = Query->get_text();
*/
filter.queryString = Query->get_text(); // full query string from Query Entry
filter.queryFileName = Query->get_text(); // for now Query is only by file name
return filter;
}
void FileCatalog::filterChanged () {
//TODO !!! there is too many repetitive and unnecessary executions of
// " fileBrowser->applyFilter (getFilter()); " throughout the code
// this needs further analysis and cleanup
fileBrowser->applyFilter (getFilter());
_refreshProgressBar();
}
@ -1192,6 +1249,20 @@ void FileCatalog::trashChanged () {
bTrash->set_image(*iTrashFull);
}
}
void FileCatalog::buttonQueryClearPressed () {
Query->set_text("");
FileCatalog::executeQuery ();
}
void FileCatalog::executeQuery(){
// if BrowsePath text was changed, do a full browse;
// otherwise filter only
if (BrowsePath->get_text()!=selectedDirectory)
buttonBrowsePathPressed ();
else
FileCatalog::filterChanged ();
}
void FileCatalog::buttonBrowsePathPressed () {
Glib::ustring BrowsePathValue = BrowsePath->get_text();
@ -1222,7 +1293,7 @@ void FileCatalog::buttonBrowsePathPressed () {
}
else
// error, likely path not found: show red arrow
buttonBrowsePath->set_image (*iRightArrow_red);
buttonBrowsePath->set_image (*iRefreshRed);
}
void FileCatalog::tbLeftPanel_1_visible (bool visible){
@ -1394,6 +1465,12 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
BrowsePath->grab_focus();
return true;
}
case GDK_f:
if (!alt){
Query->select_region(0, Query->get_text_length());
Query->grab_focus();
return true;
}
}
}

View File

@ -90,12 +90,17 @@ class FileCatalog : public Gtk::VBox,
Gtk::Image* iranked[5], *igranked[5];
Gtk::Image* iCLabeled[5], *igCLabeled[5];
Gtk::Image *iTrashEmpty, *iTrashFull;
Gtk::Image *iRightArrow_red, *iRightArrow;
//Gtk::Image *iRightArrow_red, *iRightArrow;
Gtk::Image *iRefreshWhite, *iRefreshRed;
Gtk::Image *iLeftPanel_1_Show, *iLeftPanel_1_Hide, *iRightPanel_1_Show, *iRightPanel_1_Hide;
Gtk::Image *iQueryClear;
Gtk::Entry* BrowsePath;
Gtk::Button* buttonBrowsePath;
sigc::connection BrowsePathconn;
Gtk::Entry* Query;
Gtk::Button* buttonQueryClear;
double hScrollPos[14];
double vScrollPos[14];
int lastScrollPos;
@ -195,6 +200,8 @@ class FileCatalog : public Gtk::VBox,
void zoomOut ();
void buttonBrowsePathPressed ();
void buttonQueryClearPressed ();
void executeQuery ();
void tbLeftPanel_1_toggled ();
void tbLeftPanel_1_visible (bool visible);

View File

@ -138,6 +138,7 @@ void Options::setDefaults () {
tunnelMetaData = false;
histogramPosition = 2;
showProfileSelector = true;
FileBrowserToolbarSingleRow = true;
cutOverlayBrush = std::vector<double> (4);
cutOverlayBrush[3] = 0.667; // :-p
@ -355,6 +356,7 @@ if (keyFile.has_group ("GUI")) {
if (keyFile.has_key ("GUI", "CutOverlayBrush")) cutOverlayBrush = keyFile.get_double_list ("GUI", "CutOverlayBrush");
if (keyFile.has_key ("GUI", "HistogramPosition")) histogramPosition = keyFile.get_integer ("GUI", "HistogramPosition");
if (keyFile.has_key ("GUI", "ShowProfileSelector")) showProfileSelector = keyFile.get_boolean ("GUI", "ShowProfileSelector");
if (keyFile.has_key ("GUI", "FileBrowserToolbarSingleRow")) FileBrowserToolbarSingleRow = keyFile.get_boolean ("GUI", "FileBrowserToolbarSingleRow");
}
@ -506,6 +508,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush);
keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition);
keyFile.set_boolean ("GUI", "ShowProfileSelector", showProfileSelector);
keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow);
//Glib::ArrayHandle<int> crvopen = crvOpen;
//keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen);

View File

@ -146,6 +146,7 @@ class Options {
bool tunnelMetaData; // Pass through IPTC and XMP unchanged
int histogramPosition; // 0=disabled, 1=left pane, 2=right pane
bool showProfileSelector;
bool FileBrowserToolbarSingleRow;
Options ();

View File

@ -433,6 +433,11 @@ Gtk::Widget* Preferences::getGeneralPanel () {
hbworkflow2->pack_start (*ckbShowProfileSelector, Gtk::PACK_SHRINK, 4);
vbworkflow->pack_start (*hbworkflow2, Gtk::PACK_SHRINK, 4);
Gtk::HBox* hbworkflow3 = Gtk::manage( new Gtk::HBox () );
ckbFileBrowserToolbarSingleRow = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_FILEBROWSERTOOLBARSINGLEROW")) );
hbworkflow3->pack_start (*ckbFileBrowserToolbarSingleRow, Gtk::PACK_SHRINK, 4);
vbworkflow->pack_start (*hbworkflow3, Gtk::PACK_SHRINK, 0);
fworklflow->add (*vbworkflow);
mvbsd->pack_start (*fworklflow, Gtk::PACK_SHRINK, 4);
@ -973,6 +978,7 @@ void Preferences::storePreferences () {
moptions.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2;
moptions.showProfileSelector = ckbShowProfileSelector->get_active();
moptions.FileBrowserToolbarSingleRow = ckbFileBrowserToolbarSingleRow->get_active();
moptions.overwriteOutputFile = chOverwriteOutputFile->get_active ();
// Sounds
@ -1077,7 +1083,7 @@ void Preferences::fillPreferences () {
ckbHistogramPositionLeft->set_active(moptions.histogramPosition==1);
ckbShowProfileSelector->set_active(moptions.showProfileSelector);
ckbFileBrowserToolbarSingleRow->set_active(moptions.FileBrowserToolbarSingleRow);
//darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath );
//updateDFinfos();

View File

@ -122,6 +122,7 @@ class Preferences : public Gtk::Dialog {
Gtk::CheckButton* ckbHistogramPositionLeft;
Gtk::CheckButton* ckbShowProfileSelector;
Gtk::CheckButton* ckbFileBrowserToolbarSingleRow;
Options moptions;