diff --git a/rtdata/images/Dark/actions/nav-next.png b/rtdata/images/Dark/actions/nav-next.png
new file mode 100644
index 000000000..a3e8ed0b0
Binary files /dev/null and b/rtdata/images/Dark/actions/nav-next.png differ
diff --git a/rtdata/images/Dark/actions/nav-prev.png b/rtdata/images/Dark/actions/nav-prev.png
new file mode 100644
index 000000000..cd621d372
Binary files /dev/null and b/rtdata/images/Dark/actions/nav-prev.png differ
diff --git a/rtdata/images/Dark/actions/nav-sync.png b/rtdata/images/Dark/actions/nav-sync.png
new file mode 100644
index 000000000..cbad9711e
Binary files /dev/null and b/rtdata/images/Dark/actions/nav-sync.png differ
diff --git a/rtdata/images/Light/actions/nav-next.png b/rtdata/images/Light/actions/nav-next.png
new file mode 100644
index 000000000..d68e1df60
Binary files /dev/null and b/rtdata/images/Light/actions/nav-next.png differ
diff --git a/rtdata/images/Light/actions/nav-prev.png b/rtdata/images/Light/actions/nav-prev.png
new file mode 100644
index 000000000..ad37367ba
Binary files /dev/null and b/rtdata/images/Light/actions/nav-prev.png differ
diff --git a/rtdata/images/Light/actions/nav-sync.png b/rtdata/images/Light/actions/nav-sync.png
new file mode 100644
index 000000000..eb8445a40
Binary files /dev/null and b/rtdata/images/Light/actions/nav-sync.png differ
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 97b50d105..17f531128 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -88,7 +88,7 @@ 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 a path to navigate to.\nCtrl-O to focus the path text box.\nEnter / Ctrl-Enter (in the File Browser) to browse there;\n\nPath shortcuts:\n ~ - user's home directory\n ! - user's pictures directory
+FILEBROWSER_BROWSEPATHHINT;Type a path to navigate to.\nCtrl-O to focus to the path text box.\nEnter / Ctrl-Enter to browse there;\nEsc to clear changes.\nShift-Esc to remove focus.\n\n\nPath shortcuts:\n ~ - user's home directory\n ! - user's pictures directory
FILEBROWSER_CACHECLEARFROMFULL;Clear from cache - full
FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial
FILEBROWSER_CACHE;Cache
@@ -149,7 +149,7 @@ FILEBROWSER_POPUPUNTRASH;Remove from trash
FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory
FILEBROWSER_PROCESSINGSETTINGS;Settings
FILEBROWSER_QUERYBUTTONHINT;Clear the Find query
-FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box (in the File Browser).\nEnter to commence search.\nEscape to clear.
+FILEBROWSER_QUERYHINT;Type a partial filename to search for or a comma-separated list.\nE.g. 1001,1004,1199 \n\nCtrl-F to focus to the Find text box.\nEnter to commence search.\nEsc to clear.\nShift-Esc to remove focus.
FILEBROWSER_QUERYLABEL; Find:
FILEBROWSER_RENAMEDLGLABEL;Rename file
FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to:
@@ -163,7 +163,7 @@ FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5<
FILEBROWSER_SHOWDIRHINT;Clear all filters.\nShortcut: D
FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7
FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6
-FILEBROWSER_SHOWEXIFINFO;Show Exif info.\nShortcut: i
+FILEBROWSER_SHOWEXIFINFO;Show Exif info.\nShortcut: i\n\nShortcut in Single Editor Tab: Alt-i
FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue
FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star.\nShortcut: 1
FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star.\nShortcut: 2
@@ -182,8 +182,8 @@ FILEBROWSER_STOPPROCESSING;Stop Processing
FILEBROWSER_THUMBSIZE;Thumbnail size
FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives
FILEBROWSER_USETEMPLATE;Use template:
-FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: +
-FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: -
+FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\nShortcut: +\n\nShortcut in Single Editor Tab: Alt +
+FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\nShortcut: -\n\nShortcut in Single Editor Tab: Alt -
GENERAL_ABOUT;About
GENERAL_AFTER;After
GENERAL_AUTO;Automatic
@@ -497,6 +497,9 @@ IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of the original tr
IPTCPANEL_TRANSREFERENCE;Trans. reference
MAIN_BUTTON_EXIT;Exit
MAIN_BUTTON_FULLSCREEN;Fullscreen
+MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the Next image relative to image open in Editor\nShortcut: Shift-F4\n\nTo navigate to the Next image relative to thumbnail selected in File Browser\nShortcut: F4
+MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the Previous image relative to image open in Editor\nShortcut: Shift-F3 \n\nTo navigate to the Previous image relative to thumbnail selected in File Browser\nShortcut: F3
+MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser with the Editor to reveal the thumbnail of the currently open image, and clear filters in File Browser \nShortcut: x\n\nAs above, but without clearing filters in File Browser\nShortcut: y\n(Note that thumbnail of the open file will not be shown if filtered out).
MAIN_BUTTON_PREFERENCES;Preferences
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+Q
MAIN_BUTTON_QUEUE;Put to Queue
@@ -909,8 +912,8 @@ TP_CHMIXER_LABEL;Channel Mixer
TP_CHMIXER_RED;Red Channel
TP_CHROMATABERR_LABEL;Chromatic Aberration
TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally
-TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\nShortcut: [
-TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]
+TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\nShortcut: [\n\nShortcut in Single Editor Tab: Alt-[
+TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]\n\nShortcut in Single Editor Tab: Alt-]
TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically
TP_COLORAPP_ADAPTSCENE;Adaptation scene luminosity (cd/m²)
TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environnement\n(usually 2000cd/m²)
@@ -1324,7 +1327,7 @@ ZOOMBAR_SCALE;Scale
ZOOMBAR_SMALL;Small
ZOOMPANEL_100;(100%)
ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window
-ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: 1
+ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z
ZOOMPANEL_ZOOMFITSCREEN;Fit to screen\nShortcut: f
ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: +
ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: -
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index e544e2e38..614b38ce7 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -223,6 +223,35 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
iops->pack_end (*iareapanel->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1);
iops->pack_end (*vsepz3, Gtk::PACK_SHRINK, 2);
+ // Navigation buttons
+ Gtk::Image *navPrevImage = Gtk::manage (new RTImage ("nav-prev.png"));
+ navPrevImage->set_padding(0,0);
+ navPrev = Gtk::manage (new Gtk::Button ());
+ navPrev->add(*navPrevImage);
+ navPrev->set_relief(Gtk::RELIEF_NONE);
+ navPrev->set_tooltip_markup(M("MAIN_BUTTON_NAVPREV_TOOLTIP"));
+
+ Gtk::Image *navNextImage = Gtk::manage (new RTImage ("nav-next.png"));
+ navNextImage->set_padding(0,0);
+ navNext = Gtk::manage (new Gtk::Button ());
+ navNext->add(*navNextImage);
+ navNext->set_relief(Gtk::RELIEF_NONE);
+ navNext->set_tooltip_markup(M("MAIN_BUTTON_NAVNEXT_TOOLTIP"));
+
+ Gtk::Image *navSyncImage = Gtk::manage (new RTImage ("nav-sync.png"));
+ navSyncImage->set_padding(0,0);
+ navSync = Gtk::manage (new Gtk::Button ());
+ navSync->add(*navSyncImage);
+ navSync->set_relief(Gtk::RELIEF_NONE);
+ navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP"));
+
+ if (!simpleEditor && !options.tabbedUI){
+ iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0);
+ iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0);
+ iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0);
+ iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0);
+ }
+
editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0);
editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0);
editbox->show_all ();
@@ -295,6 +324,10 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) );
queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) );
sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) );
+ navPrev->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openPreviousEditorImage) );
+ navNext->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openNextEditorImage) );
+ navSync->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::syncFileBrowser) );
+
ShowHideSidePanelsconn = tbShowHideSidePanels->signal_toggled().connect ( sigc::mem_fun(*this, &EditorPanel::toggleSidePanels), true);
if (tbTopPanel_1)
tbTopPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbTopPanel_1_toggled) );
@@ -866,7 +899,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
case GDK_underscore:
iareapanel->imageArea->zoomPanel->zoomOutClicked();
return true;
- case GDK_1:
+ case GDK_z://GDK_1
iareapanel->imageArea->zoomPanel->zoom11Clicked();
return true;
@@ -909,6 +942,18 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
case GDK_F5:
openThm->openDefaultViewer(event->state & GDK_SHIFT_MASK ? 2 : 1);
return true;
+ case GDK_y: // synchronize filebrowser with image in Editor
+ if (!simpleEditor && fPanel && fname!=""){
+ fPanel->fileCatalog->selectImage(fname, false);
+ return true;
+ }
+ break; // to avoid gcc complain
+ case GDK_x: // clear filters and synchronize filebrowser with image in Editor
+ if (!simpleEditor && fPanel && fname!=""){
+ fPanel->fileCatalog->selectImage(fname, true);
+ return true;
+ }
+ break; // to avoid gcc complain
}
}
else {
@@ -949,12 +994,34 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
return true;
}
}
+
+ if (shift){
+ switch (event->keyval) {
+ case GDK_F3: // open Previous image from Editor's perspective
+ if (!simpleEditor && fPanel && fname!=""){
+ EditorPanel::openPreviousEditorImage();
+ return true;
+ }
+ break; // to avoid gcc complain
+ case GDK_F4: // open next image from Editor's perspective
+ if (!simpleEditor && fPanel && fname!=""){
+ EditorPanel::openNextEditorImage();
+ return true;
+ }
+ break; // to avoid gcc complain
+ }
+ }
- if(tpc->getToolBar()->handleShortcutKey(event))
+ if(tpc->getToolBar() && tpc->getToolBar()->handleShortcutKey(event))
return true;
if(tpc->handleShortcutKey(event))
return true;
+ if (!simpleEditor && fPanel){
+ if (fPanel->handleShortcutKey(event))
+ return true;
+ }
+
return false;
}
@@ -1163,6 +1230,22 @@ void EditorPanel::sendToGimpPressed () {
sendtogimp->set_sensitive(false);
}
+
+void EditorPanel::openPreviousEditorImage() {
+ if (!simpleEditor && fPanel && fname!="")
+ fPanel->fileCatalog->openNextPreviousEditorImage(fname, true, NAV_PREVIOUS);
+}
+
+void EditorPanel::openNextEditorImage() {
+ if (!simpleEditor && fPanel && fname!="")
+ fPanel->fileCatalog->openNextPreviousEditorImage(fname, true, NAV_NEXT);
+}
+
+void EditorPanel::syncFileBrowser() { // synchronize filebrowser with image in Editor
+ if (!simpleEditor && fPanel && fname!="")
+ fPanel->fileCatalog->selectImage(fname, true);
+}
+
bool EditorPanel::idle_sendToGimp( ProgressConnector *pc){
rtengine::IImage16* img = pc->returnValue();
diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h
index 2a56cbaf1..bd47e87d4 100644
--- a/rtgui/editorpanel.h
+++ b/rtgui/editorpanel.h
@@ -78,6 +78,9 @@ class EditorPanel : public Gtk::VBox,
Gtk::Button* queueimg;
Gtk::Button* saveimgas;
Gtk::Button* sendtogimp;
+ Gtk::Button* navSync;
+ Gtk::Button* navNext;
+ Gtk::Button* navPrev;
ImageAreaPanel* iareapanel;
PreviewHandler* previewHandler;
@@ -105,7 +108,7 @@ class EditorPanel : public Gtk::VBox,
bool firstProcessingDone;
Thumbnail* openThm; // may get invalid on external delete event
- Glib::ustring fname; // must be safed seperately
+ Glib::ustring fname; // must be saved separately
rtengine::InitialImage* isrc;
rtengine::StagedImageProcessor* ipc;
@@ -174,6 +177,9 @@ class EditorPanel : public Gtk::VBox,
void saveAsPressed ();
void queueImgPressed ();
void sendToGimpPressed ();
+ void openNextEditorImage ();
+ void openPreviousEditorImage ();
+ void syncFileBrowser ();
void tbTopPanel_1_visible (bool visible);
bool CheckSidePanelsVisibility();
diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc
index f975c74bd..997c694af 100644
--- a/rtgui/filebrowser.cc
+++ b/rtgui/filebrowser.cc
@@ -808,38 +808,51 @@ void FileBrowser::openDefaultViewer (int destination) {
bool FileBrowser::keyPressed (GdkEventKey* event) {
- if ((event->keyval==GDK_C || event->keyval==GDK_c) && event->state & GDK_CONTROL_MASK) {
+ bool ctrl = event->state & GDK_CONTROL_MASK;
+ bool shift = event->state & GDK_SHIFT_MASK;
+ bool alt = event->state & GDK_MOD1_MASK;
+
+ if ((event->keyval==GDK_C || event->keyval==GDK_c) && ctrl) {
copyProfile ();
return true;
}
- else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) {
+ else if ((event->keyval==GDK_V || event->keyval==GDK_v) && ctrl && !shift) {
pasteProfile ();
return true;
}
- else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) {
+ else if ((event->keyval==GDK_V || event->keyval==GDK_v) && ctrl && shift) {
partPasteProfile ();
return true;
}
- else if (event->keyval==GDK_Delete && !(event->state & GDK_SHIFT_MASK)) {
+ else if (event->keyval==GDK_Delete && !shift) {
menuItemActivated (trash);
return true;
}
- else if (event->keyval==GDK_Delete && event->state & GDK_SHIFT_MASK) {
+ else if (event->keyval==GDK_Delete && shift) {
menuItemActivated (untrash);
return true;
}
- else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && event->state & GDK_CONTROL_MASK) {
+ else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && ctrl) {
menuItemActivated (develop);
return true;
}
- else if ((event->keyval==GDK_A || event->keyval==GDK_a) && event->state & GDK_CONTROL_MASK) {
+ else if ((event->keyval==GDK_A || event->keyval==GDK_a) && ctrl) {
menuItemActivated (selall);
return true;
}
- else if (event->keyval==GDK_F2 && !(event->state & GDK_CONTROL_MASK)) {
+ else if (event->keyval==GDK_F2 && !ctrl) {
menuItemActivated (rename);
return true;
}
+ else if (event->keyval==GDK_F3 && !(ctrl || shift || alt)) { // open Previous image from FileBrowser perspective
+ FileBrowser::openPrevImage ();
+ return true;
+ }
+ else if (event->keyval==GDK_F4 && !(ctrl || shift || alt)) { // open Next image from FileBrowser perspective
+ FileBrowser::openNextImage ();
+ return true;
+ }
+
else if (event->keyval==GDK_F5) {
int dest = 1;
if (event->state & GDK_SHIFT_MASK)
@@ -1103,51 +1116,151 @@ void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionD
}
void FileBrowser::openNextImage () {
- // TODO: Check for Linux
- #ifdef WIN32
- Glib::RWLock::ReaderLock l(entryRW);
- #endif
+ // TODO: Check for Linux
+ #ifdef WIN32
+ Glib::RWLock::ReaderLock l(entryRW);
+ #endif
- if (!fd.empty()) {
- for (size_t i=fd.size()-1; i>0; i--)
- if (editedFiles.find (fd[i]->filename)!=editedFiles.end())
- if (i entries;
- entries.push_back ((static_cast(fd[i+1]))->thumbnail);
- tbl->openRequested (entries);
- return;
+ if (!fd.empty() && selected.size()>0 && !options.tabbedUI) {
+
+ for (size_t i=0; ithumbnail->getFileName()==fd[i]->filename) {// located 1-st image in current selection
+ if (ifiltered/*checkFilter (fd[k])*/){
+ // clear current selection
+ for (size_t j=0; jselected = false;
+ selected.clear ();
+
+ // set new selection
+ fd[k]->selected = true;
+ selected.push_back (fd[k]);
+ //queue_draw ();
+ notifySelectionListener ();
+
+ // scroll to the selected position
+ double h1, v1;
+ getScrollPosition(h1,v1);
+
+ double h2=selected[0]->getStartX();
+ double v2=selected[0]->getStartY();
+
+ // scroll only when selected[0] is outside of the displayed bounds
+ if (h2+fd[k]->getMinimalWidth()-h1 > get_width())
+ setScrollPosition(h2-(get_width()-fd[k]->getMinimalWidth()),v2);
+ if (h1>h2)
+ setScrollPosition(h2,v2);
+
+ // open the selected image
+ std::vector entries;
+ entries.push_back ((static_cast(fd[k]))->thumbnail);
+ tbl->openRequested (entries);
+ return;
+ }
+ }
}
- if (tbl) {
- std::vector entries;
- entries.push_back ((static_cast(fd[0]))->thumbnail);
- tbl->openRequested (entries);
+ }
}
}
}
void FileBrowser::openPrevImage () {
- // TODO: Check for Linux
- #ifdef WIN32
- Glib::RWLock::ReaderLock l(entryRW);
- #endif
+ // TODO: Check for Linux
+ #ifdef WIN32
+ Glib::RWLock::ReaderLock l(entryRW);
+ #endif
- if (!fd.empty()) {
- for (size_t i=0; ifilename)!=editedFiles.end())
+ if (!fd.empty() && selected.size()>0 && !options.tabbedUI) {
+
+ for (size_t i=1; ithumbnail->getFileName()==fd[i]->filename) {// located 1-st image in current selection
if (i>0 && tbl) {
- std::vector entries;
- entries.push_back ((static_cast(fd[i-1]))->thumbnail);
- tbl->openRequested (entries);
- return;
+ // find the first not-filtered-out (previous) image
+ for (size_t k=i-1; k>=0; k--){
+ if (!fd[k]->filtered/*checkFilter (fd[k])*/){
+ // clear current selection
+ for (size_t j=0; jselected = false;
+ selected.clear ();
+
+ // set new selection
+ fd[k]->selected = true;
+ selected.push_back (fd[k]);
+ //queue_draw ();
+ notifySelectionListener ();
+
+ // scroll to the selected position
+ double h1, v1;
+ getScrollPosition(h1,v1);
+
+ double h2=selected[0]->getStartX();
+ double v2=selected[0]->getStartY();
+
+ // scroll only when selected[0] is outside of the displayed bounds
+ if (h2+fd[k]->getMinimalWidth()-h1 > get_width())
+ setScrollPosition(h2-(get_width()-fd[k]->getMinimalWidth()),v2);
+ if (h1>h2)
+ setScrollPosition(h2,v2);
+
+ // open the selected image
+ std::vector entries;
+ entries.push_back ((static_cast(fd[k]))->thumbnail);
+ tbl->openRequested (entries);
+ return;
+ }
+ }
}
- if (tbl) {
- std::vector entries;
- entries.push_back ((static_cast(fd[fd.size()-1]))->thumbnail);
- tbl->openRequested (entries);
+ }
}
}
}
+
+void FileBrowser::selectImage (Glib::ustring fname) {
+
+ // need to clear the filter in filecatalog
+
+ if (!fd.empty() && !options.tabbedUI) {
+ for (size_t i=0; ifilename && !fd[i]->filtered) {
+ // matching file found for sync
+
+ // clear current selection
+ for (size_t j=0; jselected = false;
+ selected.clear ();
+
+ // set new selection
+ fd[i]->selected = true;
+ selected.push_back (fd[i]);
+ queue_draw ();
+ notifySelectionListener ();
+
+ // scroll to the selected position
+ double h=selected[0]->getStartX();
+ double v=selected[0]->getStartY();
+ setScrollPosition(h,v);
+
+ return;
+ }
+ }
+ }
+}
+
+void FileBrowser::openNextPreviousEditorImage (Glib::ustring fname, eRTNav nextPrevious) {
+
+ // let FileBrowser acquire Editor's perspective
+ selectImage (fname);
+
+ // now switch to the requested image
+ if (nextPrevious==NAV_NEXT)
+ openNextImage();
+ else if (nextPrevious==NAV_PREVIOUS)
+ openPrevImage();
+}
+
int refreshThumbImagesUI (void* data) {
(static_cast(data))->_thumbRearrangementNeeded ();
return 0;
diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h
index 529b1f4a6..5188f19f9 100644
--- a/rtgui/filebrowser.h
+++ b/rtgui/filebrowser.h
@@ -154,6 +154,8 @@ class FileBrowser : public ThumbBrowserBase,
void copyProfile ();
void pasteProfile ();
void partPasteProfile ();
+ void selectImage (Glib::ustring fname);
+ void openNextPreviousEditorImage (Glib::ustring fname, eRTNav eNextPrevious);
void openDefaultViewer (int destination);
diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc
index 65a2ae45e..3b5734e9f 100644
--- a/rtgui/filecatalog.cc
+++ b/rtgui/filecatalog.cc
@@ -94,6 +94,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) :
hbToolBar1->pack_start (*hbBrowsePath, Gtk::PACK_EXPAND_WIDGET,0);
BrowsePath->signal_activate().connect (sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed)); //respond to the Enter key
+ BrowsePath->signal_key_press_event().connect(sigc::mem_fun(*this, &FileCatalog::BrowsePath_key_pressed));
//setup Query
iQueryClear = new RTImage("gtk-close-small.png");
@@ -487,7 +488,7 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring
previewsToLoad = 0;
previewsLoaded = 0;
// if openfile exists, we have to open it first (it is a command line argument)
- if (openfile!="")
+ if (!openfile.empty())
addAndOpenFile (openfile);
selectedDirectory = dir->get_parse_name();
@@ -643,6 +644,17 @@ void FileCatalog::previewsFinishedUI () {
fileBrowser->applyFilter (getFilter()); // refresh total image count
_refreshProgressBar();
filepanel->loadingThumbs(M("PROGRESSBAR_READY"),0);
+
+ if (!imageToSelect_fname.empty()){
+ fileBrowser->selectImage(imageToSelect_fname);
+ imageToSelect_fname = "";
+ }
+
+ if (!refImageForOpen_fname.empty() && actionNextPrevious!=NAV_NONE){
+ fileBrowser->openNextPreviousEditorImage(refImageForOpen_fname,actionNextPrevious);
+ refImageForOpen_fname = "";
+ actionNextPrevious = NAV_NONE;
+ }
}
void FileCatalog::previewsFinished (int dir_id) {
@@ -968,7 +980,7 @@ void FileCatalog::renameRequested (std::vector tbe) {
continue;
// if no extension is given, concatenate the extension of the original file
Glib::ustring ext = getExtension (nBaseName);
- if (ext=="")
+ if (ext.empty())
nBaseName += "." + getExtension (baseName);
Glib::ustring nfname = Glib::build_filename (dirName, nBaseName);
@@ -1061,6 +1073,9 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick
//was shift key pressed
bool shift_down = modifierKey & GDK_SHIFT_MASK;
+ // The event is process here, we can clear modifierKey now, it'll be set again on the next even
+ modifierKey = 0;
+
for (int i=0; i<18; i++)
bCateg[i].block (true);
@@ -1337,7 +1352,7 @@ void FileCatalog::filterChanged () {
void FileCatalog::reparseDirectory () {
- if (selectedDirectory=="")
+ if (selectedDirectory.empty())
return;
if (!safe_file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) {
@@ -1528,14 +1543,19 @@ void FileCatalog::executeQuery(){
}
bool FileCatalog::Query_key_pressed (GdkEventKey *event){
- switch (event->keyval)
- {
- case GDK_Escape:
- // Clear Query if the Escape character is pressed within it
- FileCatalog::buttonQueryClearPressed ();
- return true;
- default: return false;
- }
+
+ bool shift = event->state & GDK_SHIFT_MASK;
+
+ switch (event->keyval) {
+ case GDK_Escape:
+ // Clear Query if the Escape character is pressed within it
+ if (!shift){
+ FileCatalog::buttonQueryClearPressed ();
+ return true;
+ }
+ default:
+ return false;
+ }
}
void FileCatalog::updateFBQueryTB (bool singleRow) {
@@ -1573,7 +1593,7 @@ void FileCatalog::buttonBrowsePathPressed () {
DecodedPathPrefix = safe_get_user_picture_dir();
}
- if (DecodedPathPrefix!=""){
+ if (!DecodedPathPrefix.empty()){
BrowsePathValue = Glib::ustring::compose ("%1%2",DecodedPathPrefix,BrowsePathValue.substr (1,BrowsePath->get_text_length()-1));
BrowsePath->set_text(BrowsePathValue);
}
@@ -1588,6 +1608,24 @@ void FileCatalog::buttonBrowsePathPressed () {
buttonBrowsePath->set_image (*iRefreshRed);
}
+bool FileCatalog::BrowsePath_key_pressed (GdkEventKey *event){
+
+ bool shift = event->state & GDK_SHIFT_MASK;
+
+ switch (event->keyval) {
+ case GDK_Escape:
+ // On Escape character Reset BrowsePath to selectedDirectory
+ if (!shift){
+ BrowsePath->set_text(selectedDirectory);
+ // place cursor at the end
+ BrowsePath->select_region(BrowsePath->get_text_length(), BrowsePath->get_text_length());
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
void FileCatalog::tbLeftPanel_1_visible (bool visible){
if (visible)
tbLeftPanel_1->show();
@@ -1638,6 +1676,65 @@ void FileCatalog::toggleSidePanels(){
tbRightPanel_1->set_active (!bAllSidePanelsVisible);
}
+void FileCatalog::selectImage (Glib::ustring fname, bool clearFilters) {
+
+ Glib::ustring dirname = Glib::path_get_dirname(fname);
+ if (!dirname.empty()){
+ BrowsePath->set_text(dirname);
+
+
+ if (clearFilters){ // clear all filters
+ Query->set_text("");
+ categoryButtonToggled(bFilterClear,false);
+ // disable exif filters
+ if (filterPanel->isEnabled()) filterPanel->setEnabled (false);
+ }
+
+ if (BrowsePath->get_text()!=selectedDirectory){
+ // reload or refresh thumbs and select image
+ buttonBrowsePathPressed ();
+ // the actual selection of image will be handled asynchronously at the end of FileCatalog::previewsFinishedUI
+ imageToSelect_fname = fname;
+ }
+ else{
+ // FileCatalog::filterChanged ();//this will be replaced by queue_draw() in fileBrowser->selectImage
+ fileBrowser->selectImage(fname);
+ imageToSelect_fname = "";
+ }
+ }
+}
+
+
+void FileCatalog::openNextPreviousEditorImage (Glib::ustring fname, bool clearFilters, eRTNav nextPrevious) {
+
+ Glib::ustring dirname = Glib::path_get_dirname(fname);
+ if (!dirname.empty()){
+ BrowsePath->set_text(dirname);
+
+
+ if (clearFilters){ // clear all filters
+ Query->set_text("");
+ categoryButtonToggled(bFilterClear,false);
+ // disable exif filters
+ if (filterPanel->isEnabled()) filterPanel->setEnabled (false);
+ }
+
+ if (BrowsePath->get_text()!=selectedDirectory){
+ // reload or refresh thumbs and select image
+ buttonBrowsePathPressed ();
+ // the actual selection of image will be handled asynchronously at the end of FileCatalog::previewsFinishedUI
+ refImageForOpen_fname = fname;
+ actionNextPrevious = nextPrevious;
+ }
+ else{
+ // FileCatalog::filterChanged ();//this was replace by queue_draw() in fileBrowser->selectImage
+ fileBrowser->openNextPreviousEditorImage(fname,nextPrevious);
+ refImageForOpen_fname = "";
+ actionNextPrevious = NAV_NONE;
+ }
+ }
+}
+
bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
bool ctrl = event->state & GDK_CONTROL_MASK;
@@ -1661,6 +1758,17 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
return true;
}
+ if (shift){
+ switch(event->keyval) {
+ case GDK_Escape:
+ BrowsePath->set_text(selectedDirectory);
+ // set focus on something neutral, this is useful to remove focus from BrowsePath and Query
+ // when need to execute a shortcut, which otherwise will be typed into those fields
+ filepanel->grab_focus();
+ return true;
+ }
+ }
+
if (!alt) {
switch(event->keyval) {
case GDK_grave:
@@ -1690,8 +1798,10 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
case GDK_Return:
case GDK_KP_Enter:
- FileCatalog::buttonBrowsePathPressed ();
- return true;
+ if (BrowsePath->is_focus()){
+ FileCatalog::buttonBrowsePathPressed ();
+ return true;
+ }
}
}
@@ -1737,7 +1847,7 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
}
}
- if (!ctrl) {
+ if (!ctrl || (alt && !options.tabbedUI)) {
switch(event->keyval) {
case GDK_bracketright:
@@ -1761,22 +1871,21 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) {
return true;
}
}
- else { // with Ctrl
+ if (ctrl && !alt) {
switch (event->keyval) {
- case GDK_o:
- if (!alt){
- BrowsePath->select_region(0, BrowsePath->get_text_length());
- BrowsePath->grab_focus();
- return true;
- }
- case GDK_f:
- if (!alt){
- Query->select_region(0, Query->get_text_length());
- Query->grab_focus();
- return true;
- }
+ case GDK_o:
+ BrowsePath->select_region(0, BrowsePath->get_text_length());
+ BrowsePath->grab_focus();
+ return true;
+ case GDK_f:
+ Query->select_region(0, Query->get_text_length());
+ Query->grab_focus();
+ return true;
}
}
+ if (fileBrowser->keyPressed(event))
+ return true;
+
return false;
}
diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h
index b53fb4324..83a5e2381 100644
--- a/rtgui/filecatalog.h
+++ b/rtgui/filecatalog.h
@@ -74,6 +74,9 @@ class FileCatalog : public Gtk::VBox,
int selectedDirectoryId;
bool enabled;
bool inTabMode; // Tab mode has e.g. different progress bar handling
+ Glib::ustring imageToSelect_fname;
+ Glib::ustring refImageForOpen_fname; // Next/previous for Editor's perspective
+ eRTNav actionNextPrevious;
FileSelectionListener* listener;
FileSelectionChangeListener* fslistener;
@@ -223,6 +226,7 @@ class FileCatalog : public Gtk::VBox,
void zoomOut ();
void buttonBrowsePathPressed ();
+ bool BrowsePath_key_pressed (GdkEventKey *event);
void buttonQueryClearPressed ();
void executeQuery ();
bool Query_key_pressed(GdkEventKey *event);
@@ -234,7 +238,9 @@ class FileCatalog : public Gtk::VBox,
void tbRightPanel_1_visible (bool visible);
void openNextImage () { fileBrowser->openNextImage(); }
- void openPrevImage () { fileBrowser->openPrevImage(); }
+ void openPrevImage () { fileBrowser->openPrevImage(); }
+ void selectImage (Glib::ustring fname, bool clearFilters);
+ void openNextPreviousEditorImage (Glib::ustring fname, bool clearFilters, eRTNav nextPrevious);
bool handleShortcutKey (GdkEventKey* event);
diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h
index 4f3c86a78..3d2303b0c 100644
--- a/rtgui/filterpanel.h
+++ b/rtgui/filterpanel.h
@@ -24,8 +24,8 @@
class FilterPanelListener {
- public:
- virtual void exifFilterChanged () {}
+ public:
+ virtual void exifFilterChanged () {}
};
class FilterPanel : public Gtk::VBox {
@@ -43,33 +43,33 @@ class FilterPanel : public Gtk::VBox {
Gtk::Entry* focalTo;
Gtk::Entry* isoFrom;
Gtk::Entry* isoTo;
- Gtk::CheckButton* enabled;
- Gtk::CheckButton* enaFNumber;
- Gtk::CheckButton* enaShutter;
- Gtk::CheckButton* enaFocalLen;
- Gtk::CheckButton* enaISO;
- Gtk::CheckButton* enaExpComp;
- Gtk::CheckButton* enaCamera;
- Gtk::CheckButton* enaLens;
- Gtk::CheckButton* enaFiletype;
+ Gtk::CheckButton* enabled;
+ Gtk::CheckButton* enaFNumber;
+ Gtk::CheckButton* enaShutter;
+ Gtk::CheckButton* enaFocalLen;
+ Gtk::CheckButton* enaISO;
+ Gtk::CheckButton* enaExpComp;
+ Gtk::CheckButton* enaCamera;
+ Gtk::CheckButton* enaLens;
+ Gtk::CheckButton* enaFiletype;
- int conns;
- sigc::connection sChange[22];
-
- ExifFilterSettings curefs;
- FilterPanelListener* listener;
-
- public:
- FilterPanel ();
-
- void setFilterPanelListener (FilterPanelListener* l) { listener = l; }
-
- void setFilter (ExifFilterSettings& defefs, bool updateLists);
+ int conns;
+ sigc::connection sChange[22];
+
+ ExifFilterSettings curefs;
+ FilterPanelListener* listener;
+
+ public:
+ FilterPanel ();
+
+ void setFilterPanelListener (FilterPanelListener* l) { listener = l; }
+
+ void setFilter (ExifFilterSettings& defefs, bool updateLists);
ExifFilterSettings getFilter ();
- bool isEnabled ();
-
-
- void valueChanged ();
+ bool isEnabled ();
+
+ void valueChanged ();
+ void setEnabled(bool enabledState){enabled->set_active(enabledState);}
};
#endif
diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h
index c2f400419..45eaf99ef 100644
--- a/rtgui/guiutils.h
+++ b/rtgui/guiutils.h
@@ -187,6 +187,12 @@ enum TOITypes {
TOI_ICON
};
+typedef enum RTNav {
+ NAV_NONE,
+ NAV_NEXT,
+ NAV_PREVIOUS
+} eRTNav;
+
/**
* @brief Handle the switch between text and image to be displayed in the HBox (to be used in a button/toolpanel)
*/
diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc
index de852e63d..c90677dcd 100644
--- a/rtgui/toolbar.cc
+++ b/rtgui/toolbar.cc
@@ -93,8 +93,9 @@ void ToolBar::setTool (ToolMode tool) {
handTool->set_active (true);
handTool->grab_focus();; // switch focus to the handTool button
}
- else if (tool==TMSpotWB)
+ else if (tool==TMSpotWB) {
if (wbTool) wbTool->set_active (true);
+ }
else if (tool==TMCropSelect)
cropTool->set_active (true);
else if (tool==TMStraighten)
@@ -199,7 +200,7 @@ void ToolBar::stra_pressed () {
bool ToolBar::handleShortcutKey (GdkEventKey* event) {
bool ctrl = event->state & GDK_CONTROL_MASK;
- bool shift = event->state & GDK_SHIFT_MASK;
+ //bool shift = event->state & GDK_SHIFT_MASK;
bool alt = event->state & GDK_MOD1_MASK;
if (!ctrl && !alt) {
diff --git a/tools/source_icons/scalable/nav-next.file b/tools/source_icons/scalable/nav-next.file
new file mode 100644
index 000000000..cf444112a
--- /dev/null
+++ b/tools/source_icons/scalable/nav-next.file
@@ -0,0 +1 @@
+nav-next.png,w19,actions
\ No newline at end of file
diff --git a/tools/source_icons/scalable/nav-next.svg b/tools/source_icons/scalable/nav-next.svg
new file mode 100644
index 000000000..123f334d9
--- /dev/null
+++ b/tools/source_icons/scalable/nav-next.svg
@@ -0,0 +1,649 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/nav-prev.file b/tools/source_icons/scalable/nav-prev.file
new file mode 100644
index 000000000..0c9254b3c
--- /dev/null
+++ b/tools/source_icons/scalable/nav-prev.file
@@ -0,0 +1 @@
+nav-prev.png,w19,actions
\ No newline at end of file
diff --git a/tools/source_icons/scalable/nav-prev.svg b/tools/source_icons/scalable/nav-prev.svg
new file mode 100644
index 000000000..4112c31fb
--- /dev/null
+++ b/tools/source_icons/scalable/nav-prev.svg
@@ -0,0 +1,649 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/nav-sync.file b/tools/source_icons/scalable/nav-sync.file
new file mode 100644
index 000000000..7a0e01b10
--- /dev/null
+++ b/tools/source_icons/scalable/nav-sync.file
@@ -0,0 +1 @@
+nav-sync.png,w14,actions
\ No newline at end of file
diff --git a/tools/source_icons/scalable/nav-sync.svg b/tools/source_icons/scalable/nav-sync.svg
new file mode 100644
index 000000000..420e2c335
--- /dev/null
+++ b/tools/source_icons/scalable/nav-sync.svg
@@ -0,0 +1,833 @@
+
+
+
+