New dual monitor editor layout, plus memory leak fix; cmake req. (see issue #348)

This commit is contained in:
Oliver Duis
2010-11-22 15:17:01 +01:00
parent eee3ca5cd7
commit e3dbe759a3
11 changed files with 324 additions and 55 deletions

View File

@@ -1,6 +1,6 @@
set (BASESOURCEFILES
batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc filterpanel.cc
editwindow.cc batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc filterpanel.cc
cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc
ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc
cachemanager.cc cacheimagedata.cc shcselector.cc perspective.cc

187
rtgui/editwindow.cc Normal file
View File

@@ -0,0 +1,187 @@
/*
* This file is part of RawTherapee.
*
* RawTherapee 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 3 of the License, or
* (at your option) any later version.
*
* RawTherapee 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 RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <editwindow.h>
#include <options.h>
#include <preferences.h>
#include <cursormanager.h>
#include <gtk\gtkwidget.h>
static EditWindow* editWnd = NULL;
// Check if the system has more than one display and option is set
bool EditWindow::isMultiDisplayEnabled() {
return options.multiDisplayMode>0 && Gdk::Screen::get_default()->get_n_monitors ()>1;
}
// Should only be created once, auto-creates window on correct display
EditWindow* EditWindow::getInstance(RTWindow* p)
{
if ( editWnd == NULL )
{
static Glib::Mutex smutex_;
Glib::Mutex::Lock lock(smutex_);
if ( editWnd == 0 )
{
editWnd = new EditWindow(p);
// Determine the other display and maximize the window on that
const Glib::RefPtr< Gdk::Window >& wnd=p->get_window();
int monNo=p->get_screen()->get_monitor_at_window (wnd);
Gdk::Rectangle lMonitorRect;
editWnd->get_screen()->get_monitor_geometry(monNo==0 ? 1:0, lMonitorRect);
editWnd->move(lMonitorRect.get_x(), lMonitorRect.get_y());
editWnd->maximize();
editWnd->show();
} else {
editWnd->show_all();
}
}
return editWnd;
}
EditWindow::EditWindow (RTWindow* p) : parent(p) , isFullscreen(false) {
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try { set_default_icon_from_file (argv0+"/images/logoicon16.png");
} catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }
#else
{ std::auto_ptr<Glib::Error> error;
set_default_icon_from_file (argv0+"/images/logoicon16.png", error);
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
set_title("RawTherapee "+ M("EDITWINDOW_TITLE"));
property_allow_shrink() = true;
set_modal(false);
set_resizable(true);
property_destroy_with_parent().set_value(false);
signal_window_state_event().connect( sigc::mem_fun(*this, &EditWindow::on_window_state_event) );
mainNB = Gtk::manage (new Gtk::Notebook ());
mainNB->set_scrollable (true);
mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &EditWindow::on_mainNB_switch_page) );
signal_key_press_event().connect( sigc::mem_fun(*this, &EditWindow::keyPressed) );
Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ());
mainBox->pack_start (*mainNB);
add (*mainBox);
show_all ();
}
void EditWindow::on_realize () {
Gtk::Window::on_realize ();
cursorManager.init (get_window());
}
bool EditWindow::on_window_state_event(GdkEventWindowState* event) {
if (!event->new_window_state) {
// Window mode
options.windowMaximized = false;
}
else if (event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) {
// Fullscreen mode
options.windowMaximized = true;
}
return true;
}
void EditWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint page_num) {
if (page_num > 1) {
EditorPanel *ep = (EditorPanel *)mainNB->get_nth_page(page_num);
ep->setAspect();
}
}
void EditWindow::addEditorPanel (EditorPanel* ep, const std::string &name) {
if (epanels.find(name)!=epanels.end()) {
// remove existing panel
mainNB->remove_page (*epanels[name]);
epanels.erase (name);
filesEdited.erase (name);
}
ep->setParent (parent);
// construct closeable tab for the image
Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
hb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FILE, Gtk::ICON_SIZE_MENU)));
hb->pack_start (*Gtk::manage (new Gtk::Label (name)));
Gtk::Button* closeb = Gtk::manage (new Gtk::Button ());
closeb->set_image (*Gtk::manage(new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU)));
closeb->set_relief (Gtk::RELIEF_NONE);
closeb->set_focus_on_click (false);
// make the button as small as possible
Glib::RefPtr<Gtk::RcStyle> style = Gtk::RcStyle::create ();
style->set_xthickness (0);
style->set_ythickness (0);
closeb->modify_style (style);
closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &EditWindow::remEditorPanel) , ep));
hb->pack_end (*closeb);
hb->set_spacing (2);
hb->show_all ();
mainNB->append_page (*ep, *hb);
mainNB->set_current_page (mainNB->page_num (*ep));
mainNB->set_tab_reorderable (*ep, true);
epanels[ name ] = ep;
filesEdited.insert ( name );
parent->fpanel->refreshEditedState (filesEdited);
}
void EditWindow::remEditorPanel (EditorPanel* ep) {
epanels.erase (ep->getShortName());
filesEdited.erase (ep->getShortName ());
parent->fpanel->refreshEditedState (filesEdited);
mainNB->remove_page (*ep);
// TODO: save options if wanted
}
bool EditWindow::keyPressed (GdkEventKey* event) {
if(event->keyval == GDK_F11) {
toggleFullscreen();
return true;
} else {
EditorPanel* ep = (EditorPanel*)mainNB->get_nth_page (mainNB->get_current_page());
return ep->handleShortcutKey (event);
}
}
void EditWindow::toggleFullscreen () {
isFullscreen ? unfullscreen() : fullscreen();
isFullscreen = !isFullscreen;
}
bool EditWindow::on_delete_event(GdkEventAny* event) {
for ( std::set <Glib::ustring>::iterator iter = filesEdited.begin(); iter != filesEdited.end();iter++ ) {
remEditorPanel(epanels[*iter]);
}
hide ();
return true;
}

57
rtgui/editwindow.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* This file is part of RawTherapee.
*
* RawTherapee 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 3 of the License, or
* (at your option) any later version.
*
* RawTherapee 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 RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EDITWINDOW_
#define _EDITWINDOW_
#include <gtkmm.h>
#include <filepanel.h>
#include <editorpanel.h>
#include <set>
class EditWindow : public Gtk::Window {
private:
RTWindow* parent;
Gtk::Notebook* mainNB;
std::set<Glib::ustring> filesEdited;
std::map<Glib::ustring, EditorPanel*> epanels;
bool isFullscreen;
void toggleFullscreen ();
public:
// Check if the system has more than one display and option is set
static bool isMultiDisplayEnabled();
// Should only be created once, auto-creates window on correct display
static EditWindow* getInstance(RTWindow* p);
EditWindow (RTWindow* p);
void addEditorPanel (EditorPanel* ep,const std::string &name);
void remEditorPanel (EditorPanel* ep);
bool keyPressed (GdkEventKey* event);
bool on_delete_event(GdkEventAny* event);
bool on_window_state_event(GdkEventWindowState* event);
void on_mainNB_switch_page(GtkNotebookPage* page, guint page_num);
void on_realize ();
};
#endif

View File

@@ -162,18 +162,16 @@ bool FilePanel::imageLoaded( Thumbnail* thm, ProgressConnector<rtengine::Initial
if (pc->returnValue() && thm) {
if (options.tabbedUI){
EditorPanel* epanel = Gtk::manage (new EditorPanel ());
parent->addEditorPanel (epanel,Glib::path_get_basename (thm->getFileName()));
epanel->open(thm, pc->returnValue() );
}
else{
parent->SetEditorCurrent();
parent->epanel->open(thm, pc->returnValue() );
}
if (options.tabbedUI) {
EditorPanel* epanel = Gtk::manage (new EditorPanel ());
parent->addEditorPanel (epanel,Glib::path_get_basename (thm->getFileName()));
epanel->open(thm, pc->returnValue() );
} else {
parent->SetEditorCurrent();
parent->epanel->open(thm, pc->returnValue() );
}
}else {
} else {
Glib::ustring msg_ = Glib::ustring("<b>") + M("MAIN_MSG_CANNOTLOAD") + " \"" + thm->getFileName() + "\" .\n</b>";
Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd.run ();

View File

@@ -121,6 +121,7 @@ void Options::setDefaults () {
overlayedFileNames = true;
showFileNames = true;
tabbedUI = false;
multiDisplayMode = 0;
int babehav[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0};
baBehav = std::vector<int> (babehav, babehav+ADDSET_PARAM_NUM);
@@ -269,6 +270,7 @@ if (keyFile.has_group ("GUI")) {
if (keyFile.has_key ("GUI", "FrameColor")) bgcolor = keyFile.get_integer ("GUI", "FrameColor");
if (keyFile.has_key ("GUI", "ProcessingQueueEnbled"))procQueueEnabled = keyFile.get_boolean ("GUI", "ProcessingQueueEnbled");
if (keyFile.has_key ("GUI", "ToolPanelsExpanded")) tpOpen = keyFile.get_integer_list ("GUI", "ToolPanelsExpanded");
if (keyFile.has_key ("GUI", "MultiDisplayMode")) multiDisplayMode = keyFile.get_integer ("GUI", "MultiDisplayMode");
//if (keyFile.has_key ("GUI", "CurvePanelsExpanded")) crvOpen = keyFile.get_integer_list ("GUI", "CurvePanelsExpanded");
}
@@ -400,6 +402,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled);
Glib::ArrayHandle<int> tpopen = tpOpen;
keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen);
keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode);
//Glib::ArrayHandle<int> crvopen = crvOpen;
//keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen);
@@ -460,7 +463,7 @@ void Options::load () {
// out which are the parent translations. Furthermore, there must be a file <Language> for each locale <Language> (<LC>) -- you cannot have
// 'French (CA)' unless there is a file 'French'.
Glib::ustring defaultTranslation = argv0 + "/languages/default";
Glib::ustring defaultTranslation = argv0 + "/languages/default";
Glib::ustring languageTranslation = "";
Glib::ustring localeTranslation = "";

View File

@@ -132,6 +132,7 @@ class Options {
bool showFileNames;
bool tabbedUI;
int previewSizeTab,previewSizeBrowser;
int multiDisplayMode; // 0=none, 1=Edit panels on other display
Options ();

View File

@@ -330,6 +330,7 @@ Gtk::Widget* Preferences::getGeneralPanel () {
editorLayout->append_text (M("PREFERENCES_SINGLETAB"));
editorLayout->append_text (M("PREFERENCES_MULTITAB"));
editorLayout->append_text (M("PREFERENCES_MULTITABDUALMON"));
editorLayout->set_active (1);
hbworkflow->pack_start (*flayoutlab, Gtk::PACK_SHRINK, 4);
@@ -761,7 +762,9 @@ void Preferences::storePreferences () {
for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++)
moptions.baBehav[adjs->get_value (behavColumns.addsetid)] = adjs->get_value (behavColumns.badd);
moptions.tabbedUI = (bool)editorLayout->get_active_row_number();
int editorMode=editorLayout->get_active_row_number();
moptions.tabbedUI = (editorMode>0);
moptions.multiDisplayMode = editorMode==2 ? 1:0;
moptions.overwriteOutputFile = chOverwriteOutputFile->get_active ();
}
@@ -837,7 +840,11 @@ void Preferences::fillPreferences () {
saveParamsCache->set_active (moptions.saveParamsCache);
loadParamsPreference->set_active (moptions.paramsLoadLocation);
editorLayout->set_active(moptions.tabbedUI);
if (!moptions.tabbedUI)
editorLayout->set_active(0);
else
editorLayout->set_active(moptions.multiDisplayMode ? 2 : 1);
darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath );
updateDFinfos();

View File

@@ -20,6 +20,7 @@
#include <options.h>
#include <preferences.h>
#include <cursormanager.h>
#include <editwindow.h>
RTWindow::RTWindow () {
@@ -118,7 +119,7 @@ RTWindow::RTWindow () {
add (*mainBox);
show_all ();
if(options.tabbedUI)
if(options.tabbedUI || EditWindow::isMultiDisplayEnabled())
epanel->hide_all();
}
@@ -151,50 +152,59 @@ void RTWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint page_num) {
}
void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) {
if (EditWindow::isMultiDisplayEnabled()) {
EditWindow * wndEdit = EditWindow::getInstance(this);
wndEdit->show_all();
wndEdit->addEditorPanel(ep,name);
} else {
ep->setParent (this);
ep->setParent (this);
// construct closeable tab for the image
Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
hb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FILE, Gtk::ICON_SIZE_MENU)));
hb->pack_start (*Gtk::manage (new Gtk::Label (name)));
Gtk::Button* closeb = Gtk::manage (new Gtk::Button ());
closeb->set_image (*Gtk::manage(new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU)));
closeb->set_relief (Gtk::RELIEF_NONE);
closeb->set_focus_on_click (false);
// make the button as small as possible
Glib::RefPtr<Gtk::RcStyle> style = Gtk::RcStyle::create ();
style->set_xthickness (0);
style->set_ythickness (0);
// construct closeable tab for the image
Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
hb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FILE, Gtk::ICON_SIZE_MENU)));
hb->pack_start (*Gtk::manage (new Gtk::Label (name)));
Gtk::Button* closeb = Gtk::manage (new Gtk::Button ());
closeb->set_image (*Gtk::manage(new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU)));
closeb->set_relief (Gtk::RELIEF_NONE);
closeb->set_focus_on_click (false);
// make the button as small as possible
Glib::RefPtr<Gtk::RcStyle> style = Gtk::RcStyle::create ();
style->set_xthickness (0);
style->set_ythickness (0);
closeb->modify_style (style);
closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep));
hb->pack_end (*closeb);
hb->set_spacing (2);
hb->show_all ();
closeb->modify_style (style);
closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep));
hb->pack_end (*closeb);
hb->set_spacing (2);
hb->show_all ();
mainNB->append_page (*ep, *hb);
//ep->setAspect ();
mainNB->set_current_page (mainNB->page_num (*ep));
mainNB->set_tab_reorderable (*ep, true);
mainNB->append_page (*ep, *hb);
//ep->setAspect ();
mainNB->set_current_page (mainNB->page_num (*ep));
mainNB->set_tab_reorderable (*ep, true);
epanels[ name ] = ep;
filesEdited.insert ( name );
fpanel->refreshEditedState (filesEdited);
epanels[ name ] = ep;
filesEdited.insert ( name );
fpanel->refreshEditedState (filesEdited);
}
}
void RTWindow::remEditorPanel (EditorPanel* ep) {
if (EditWindow::isMultiDisplayEnabled()) {
EditWindow * wndEdit = EditWindow::getInstance(this);
wndEdit->remEditorPanel(ep);
} else {
//ep->saveOptions ();
epanels.erase (ep->getShortName());
filesEdited.erase (ep->getShortName ());
fpanel->refreshEditedState (filesEdited);
//ep->saveOptions ();
epanels.erase (ep->getFileName());
filesEdited.erase (ep->getFileName ());
fpanel->refreshEditedState (filesEdited);
mainNB->remove_page (*ep);
mainNB->remove_page (*ep);
if (mainNB->get_current_page () == mainNB->page_num (*bpanel))
mainNB->set_current_page (mainNB->page_num (*fpanel));
// TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel
if (mainNB->get_current_page () == mainNB->page_num (*bpanel))
mainNB->set_current_page (mainNB->page_num (*fpanel));
// TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel
}
}
bool RTWindow::keyPressed (GdkEventKey* event) {
@@ -359,15 +369,15 @@ void RTWindow::MoveFileBrowserToEditor()
bool RTWindow::on_expose_event_epanel(GdkEventExpose* event)
{
if(!options.tabbedUI)
if(!options.tabbedUI && !EditWindow::isMultiDisplayEnabled())
MoveFileBrowserToEditor();
return false; // Gtk::VBox::on_expose_event(event);
return false; // Gtk::VBox::on_expose_event(event);
}
bool RTWindow::on_expose_event_fpanel(GdkEventExpose* event)
{
if(!options.tabbedUI)
if(!options.tabbedUI && !EditWindow::isMultiDisplayEnabled())
MoveFileBrowserToMain();
return false; // Gtk::HPaned::on_expose_event(event);
}

View File

@@ -30,7 +30,6 @@ class RTWindow : public Gtk::Window, public rtengine::ProgressListener{
private:
Gtk::Notebook* mainNB;
FilePanel* fpanel;
BatchQueuePanel* bpanel;
std::set<Glib::ustring> filesEdited;
std::map<Glib::ustring, EditorPanel*> epanels;
@@ -66,7 +65,10 @@ class RTWindow : public Gtk::Window, public rtengine::ProgressListener{
void setProgressState (int state);
void error (Glib::ustring descr);
rtengine::ProgressListener* getProgressListener () { return pldBridge; }
EditorPanel* epanel;
FilePanel* fpanel;
void SetEditorCurrent();
void SetMainCurrent();
void MoveFileBrowserToEditor();