initial import

This commit is contained in:
ghorvath
2010-01-01 11:52:33 +00:00
commit 35da4bbfb7
511 changed files with 109473 additions and 0 deletions

503
rtgui/CMakeCache.txt Executable file
View File

@@ -0,0 +1,503 @@
# This is the CMakeCache file.
# For build in directory: /home/hgabor/RawTherapee/2.5/gui88/rtgui
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Path to a program.
CMAKE_AR:FILEPATH=/usr/bin/ar
//For backwards compatibility, what version of CMake commands and
// syntax should this version of CMake try to support.
CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4
//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
CMAKE_BUILD_TYPE:STRING=
//Enable/Disable color output during build.
CMAKE_COLOR_MAKEFILE:BOOL=ON
//CXX compiler.
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
//Flags used by the compiler during release minsize builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds (/MD /Ob1 /Oi
// /Ot /Oy /Gs will produce slightly less optimized but smaller
// files).
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the compiler during Release with Debug Info builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g
//C compiler.
CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
//Flags used by the compiler during release minsize builds.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds (/MD /Ob1 /Oi
// /Ot /Oy /Gs will produce slightly less optimized but smaller
// files).
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the compiler during Release with Debug Info builds.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g
//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/usr/bin/ld
//Path to a program.
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
//Flags used by the linker during the creation of modules.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/usr/bin/nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
//Path to a program.
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
//Flags used by the linker during the creation of dll's.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//If true, cmake will use relative paths in makefiles and projects.
CMAKE_USE_RELATIVE_PATHS:BOOL=OFF
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//Single output directory for building all executables.
EXECUTABLE_OUTPUT_PATH:PATH=
//Single output directory for building all libraries.
LIBRARY_OUTPUT_PATH:PATH=
//pkg-config executable
PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config
//Value Computed by CMake
Project_BINARY_DIR:STATIC=/home/hgabor/RawTherapee/2.5/gui88/rtgui
//Value Computed by CMake
Project_SOURCE_DIR:STATIC=/home/hgabor/RawTherapee/2.5/gui88/rtgui
########################
# INTERNAL cache entries
########################
//Advanced flag for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_BUILD_TOOL
CMAKE_BUILD_TOOL-ADVANCED:INTERNAL=1
//What is the target build tool cmake is generating for.
CMAKE_BUILD_TOOL:INTERNAL=/usr/bin/make
//This is the directory where this CMakeCahe.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/hgabor/RawTherapee/2.5/gui88/rtgui
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=6
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_RELEASE_VERSION:INTERNAL=patch 0
//Advanced flag for variable: CMAKE_COLOR_MAKEFILE
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//Advanced flag for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
CMAKE_CXX_COMPILER_WORKS:INTERNAL=1
//Advanced flag for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_C_COMPILER
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
CMAKE_C_COMPILER_WORKS:INTERNAL=1
//Advanced flag for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Result of TRY_COMPILE
CMAKE_DETERMINE_CXX_ABI_COMPILED:INTERNAL=TRUE
//Result of TRY_COMPILE
CMAKE_DETERMINE_C_ABI_COMPILED:INTERNAL=TRUE
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//Advanced flag for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
//Start directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/hgabor/RawTherapee/2.5/gui88/rtgui
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1
//Advanced flag for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=1
//Advanced flag for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.6
//Advanced flag for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/bin/uname
//Advanced flag for variable: CMAKE_USE_RELATIVE_PATHS
CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1
//Advanced flag for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
GIOMM_CFLAGS:INTERNAL=-I/usr/include/giomm-2.4;-I/usr/lib/giomm-2.4/include;-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include
GIOMM_CFLAGS_I:INTERNAL=
GIOMM_CFLAGS_OTHER:INTERNAL=
GIOMM_FOUND:INTERNAL=1
GIOMM_INCLUDEDIR:INTERNAL=/usr/include
GIOMM_INCLUDE_DIRS:INTERNAL=/usr/include/giomm-2.4;/usr/lib/giomm-2.4/include;/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include
GIOMM_LDFLAGS:INTERNAL=-lgiomm-2.4;-lgio-2.0;-lglibmm-2.4;-lgmodule-2.0;-lgobject-2.0;-lsigc-2.0;-lglib-2.0
GIOMM_LDFLAGS_OTHER:INTERNAL=
GIOMM_LIBDIR:INTERNAL=/usr/lib
GIOMM_LIBRARIES:INTERNAL=giomm-2.4;gio-2.0;glibmm-2.4;gmodule-2.0;gobject-2.0;sigc-2.0;glib-2.0
GIOMM_LIBRARY_DIRS:INTERNAL=
GIOMM_LIBS:INTERNAL=
GIOMM_LIBS_L:INTERNAL=
GIOMM_LIBS_OTHER:INTERNAL=
GIOMM_LIBS_PATHS:INTERNAL=
GIOMM_PREFIX:INTERNAL=/usr
GIOMM_STATIC_CFLAGS:INTERNAL=-I/usr/include/giomm-2.4;-I/usr/lib/giomm-2.4/include;-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include
GIOMM_STATIC_CFLAGS_I:INTERNAL=
GIOMM_STATIC_CFLAGS_OTHER:INTERNAL=
GIOMM_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/giomm-2.4;/usr/lib/giomm-2.4/include;/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include
GIOMM_STATIC_LDFLAGS:INTERNAL=-lgiomm-2.4;-lgio-2.0;-lglibmm-2.4;-lgmodule-2.0;-ldl;-lgobject-2.0;-lsigc-2.0;-lglib-2.0
GIOMM_STATIC_LDFLAGS_OTHER:INTERNAL=
GIOMM_STATIC_LIBDIR:INTERNAL=
GIOMM_STATIC_LIBRARIES:INTERNAL=giomm-2.4;gio-2.0;glibmm-2.4;gmodule-2.0;dl;gobject-2.0;sigc-2.0;glib-2.0
GIOMM_STATIC_LIBRARY_DIRS:INTERNAL=
GIOMM_STATIC_LIBS:INTERNAL=
GIOMM_STATIC_LIBS_L:INTERNAL=
GIOMM_STATIC_LIBS_OTHER:INTERNAL=
GIOMM_STATIC_LIBS_PATHS:INTERNAL=
GIOMM_VERSION:INTERNAL=2.18.1
GIOMM_giomm-2.4_INCLUDEDIR:INTERNAL=
GIOMM_giomm-2.4_LIBDIR:INTERNAL=
GIOMM_giomm-2.4_PREFIX:INTERNAL=
GIOMM_giomm-2.4_VERSION:INTERNAL=
GIO_CFLAGS:INTERNAL=-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GIO_CFLAGS_I:INTERNAL=
GIO_CFLAGS_OTHER:INTERNAL=
GIO_FOUND:INTERNAL=1
GIO_INCLUDEDIR:INTERNAL=/usr/include
GIO_INCLUDE_DIRS:INTERNAL=/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GIO_LDFLAGS:INTERNAL=-lgio-2.0;-lgobject-2.0;-lgmodule-2.0;-lglib-2.0
GIO_LDFLAGS_OTHER:INTERNAL=
GIO_LIBDIR:INTERNAL=/usr/lib
GIO_LIBRARIES:INTERNAL=gio-2.0;gobject-2.0;gmodule-2.0;glib-2.0
GIO_LIBRARY_DIRS:INTERNAL=
GIO_LIBS:INTERNAL=
GIO_LIBS_L:INTERNAL=
GIO_LIBS_OTHER:INTERNAL=
GIO_LIBS_PATHS:INTERNAL=
GIO_PREFIX:INTERNAL=/usr
GIO_STATIC_CFLAGS:INTERNAL=-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GIO_STATIC_CFLAGS_I:INTERNAL=
GIO_STATIC_CFLAGS_OTHER:INTERNAL=
GIO_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GIO_STATIC_LDFLAGS:INTERNAL=-lgio-2.0;-lgobject-2.0;-lgmodule-2.0;-ldl;-lglib-2.0
GIO_STATIC_LDFLAGS_OTHER:INTERNAL=
GIO_STATIC_LIBDIR:INTERNAL=
GIO_STATIC_LIBRARIES:INTERNAL=gio-2.0;gobject-2.0;gmodule-2.0;dl;glib-2.0
GIO_STATIC_LIBRARY_DIRS:INTERNAL=
GIO_STATIC_LIBS:INTERNAL=
GIO_STATIC_LIBS_L:INTERNAL=
GIO_STATIC_LIBS_OTHER:INTERNAL=
GIO_STATIC_LIBS_PATHS:INTERNAL=
GIO_VERSION:INTERNAL=2.18.2
GIO_gio-2.0_INCLUDEDIR:INTERNAL=
GIO_gio-2.0_LIBDIR:INTERNAL=
GIO_gio-2.0_PREFIX:INTERNAL=
GIO_gio-2.0_VERSION:INTERNAL=
GLIB2_CFLAGS:INTERNAL=-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GLIB2_CFLAGS_I:INTERNAL=
GLIB2_CFLAGS_OTHER:INTERNAL=
GLIB2_FOUND:INTERNAL=1
GLIB2_INCLUDEDIR:INTERNAL=/usr/include
GLIB2_INCLUDE_DIRS:INTERNAL=/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GLIB2_LDFLAGS:INTERNAL=-lglib-2.0
GLIB2_LDFLAGS_OTHER:INTERNAL=
GLIB2_LIBDIR:INTERNAL=/usr/lib
GLIB2_LIBRARIES:INTERNAL=glib-2.0
GLIB2_LIBRARY_DIRS:INTERNAL=
GLIB2_LIBS:INTERNAL=
GLIB2_LIBS_L:INTERNAL=
GLIB2_LIBS_OTHER:INTERNAL=
GLIB2_LIBS_PATHS:INTERNAL=
GLIB2_PREFIX:INTERNAL=/usr
GLIB2_STATIC_CFLAGS:INTERNAL=-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GLIB2_STATIC_CFLAGS_I:INTERNAL=
GLIB2_STATIC_CFLAGS_OTHER:INTERNAL=
GLIB2_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GLIB2_STATIC_LDFLAGS:INTERNAL=-lglib-2.0
GLIB2_STATIC_LDFLAGS_OTHER:INTERNAL=
GLIB2_STATIC_LIBDIR:INTERNAL=
GLIB2_STATIC_LIBRARIES:INTERNAL=glib-2.0
GLIB2_STATIC_LIBRARY_DIRS:INTERNAL=
GLIB2_STATIC_LIBS:INTERNAL=
GLIB2_STATIC_LIBS_L:INTERNAL=
GLIB2_STATIC_LIBS_OTHER:INTERNAL=
GLIB2_STATIC_LIBS_PATHS:INTERNAL=
GLIB2_VERSION:INTERNAL=2.18.2
GLIB2_glib-2.0_INCLUDEDIR:INTERNAL=
GLIB2_glib-2.0_LIBDIR:INTERNAL=
GLIB2_glib-2.0_PREFIX:INTERNAL=
GLIB2_glib-2.0_VERSION:INTERNAL=
GLIBMM_CFLAGS:INTERNAL=-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GLIBMM_CFLAGS_I:INTERNAL=
GLIBMM_CFLAGS_OTHER:INTERNAL=
GLIBMM_FOUND:INTERNAL=1
GLIBMM_INCLUDEDIR:INTERNAL=/usr/include
GLIBMM_INCLUDE_DIRS:INTERNAL=/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GLIBMM_LDFLAGS:INTERNAL=-lglibmm-2.4;-lgobject-2.0;-lsigc-2.0;-lglib-2.0
GLIBMM_LDFLAGS_OTHER:INTERNAL=
GLIBMM_LIBDIR:INTERNAL=/usr/lib
GLIBMM_LIBRARIES:INTERNAL=glibmm-2.4;gobject-2.0;sigc-2.0;glib-2.0
GLIBMM_LIBRARY_DIRS:INTERNAL=
GLIBMM_LIBS:INTERNAL=
GLIBMM_LIBS_L:INTERNAL=
GLIBMM_LIBS_OTHER:INTERNAL=
GLIBMM_LIBS_PATHS:INTERNAL=
GLIBMM_PREFIX:INTERNAL=/usr
GLIBMM_STATIC_CFLAGS:INTERNAL=-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include
GLIBMM_STATIC_CFLAGS_I:INTERNAL=
GLIBMM_STATIC_CFLAGS_OTHER:INTERNAL=
GLIBMM_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include
GLIBMM_STATIC_LDFLAGS:INTERNAL=-lglibmm-2.4;-lgobject-2.0;-lsigc-2.0;-lglib-2.0
GLIBMM_STATIC_LDFLAGS_OTHER:INTERNAL=
GLIBMM_STATIC_LIBDIR:INTERNAL=
GLIBMM_STATIC_LIBRARIES:INTERNAL=glibmm-2.4;gobject-2.0;sigc-2.0;glib-2.0
GLIBMM_STATIC_LIBRARY_DIRS:INTERNAL=
GLIBMM_STATIC_LIBS:INTERNAL=
GLIBMM_STATIC_LIBS_L:INTERNAL=
GLIBMM_STATIC_LIBS_OTHER:INTERNAL=
GLIBMM_STATIC_LIBS_PATHS:INTERNAL=
GLIBMM_VERSION:INTERNAL=2.18.1
GLIBMM_glibmm-2.4_INCLUDEDIR:INTERNAL=
GLIBMM_glibmm-2.4_LIBDIR:INTERNAL=
GLIBMM_glibmm-2.4_PREFIX:INTERNAL=
GLIBMM_glibmm-2.4_VERSION:INTERNAL=
GTKMM_CFLAGS:INTERNAL=-I/usr/include/gtkmm-2.4;-I/usr/lib/gtkmm-2.4/include;-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/giomm-2.4;-I/usr/lib/giomm-2.4/include;-I/usr/include/gdkmm-2.4;-I/usr/lib/gdkmm-2.4/include;-I/usr/include/pangomm-1.4;-I/usr/include/atkmm-1.6;-I/usr/include/gtk-2.0;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/lib/gtk-2.0/include;-I/usr/include/cairomm-1.0;-I/usr/include/pango-1.0;-I/usr/include/cairo;-I/usr/include/pixman-1;-I/usr/include/freetype2;-I/usr/include/libpng12;-I/usr/include/atk-1.0
GTKMM_CFLAGS_I:INTERNAL=
GTKMM_CFLAGS_OTHER:INTERNAL=
GTKMM_FOUND:INTERNAL=1
GTKMM_INCLUDEDIR:INTERNAL=/usr/include
GTKMM_INCLUDE_DIRS:INTERNAL=/usr/include/gtkmm-2.4;/usr/lib/gtkmm-2.4/include;/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/giomm-2.4;/usr/lib/giomm-2.4/include;/usr/include/gdkmm-2.4;/usr/lib/gdkmm-2.4/include;/usr/include/pangomm-1.4;/usr/include/atkmm-1.6;/usr/include/gtk-2.0;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/lib/gtk-2.0/include;/usr/include/cairomm-1.0;/usr/include/pango-1.0;/usr/include/cairo;/usr/include/pixman-1;/usr/include/freetype2;/usr/include/libpng12;/usr/include/atk-1.0
GTKMM_LDFLAGS:INTERNAL=-lgtkmm-2.4;-lgiomm-2.4;-lgdkmm-2.4;-latkmm-1.6;-lgtk-x11-2.0;-lpangomm-1.4;-lcairomm-1.0;-lglibmm-2.4;-lsigc-2.0;-lgdk-x11-2.0;-latk-1.0;-lpangoft2-1.0;-lgdk_pixbuf-2.0;-lm;-lpangocairo-1.0;-lgio-2.0;-lcairo;-lpango-1.0;-lfreetype;-lz;-lfontconfig;-lgobject-2.0;-lgmodule-2.0;-lglib-2.0
GTKMM_LDFLAGS_OTHER:INTERNAL=
GTKMM_LIBDIR:INTERNAL=/usr/lib
GTKMM_LIBRARIES:INTERNAL=gtkmm-2.4;giomm-2.4;gdkmm-2.4;atkmm-1.6;gtk-x11-2.0;pangomm-1.4;cairomm-1.0;glibmm-2.4;sigc-2.0;gdk-x11-2.0;atk-1.0;pangoft2-1.0;gdk_pixbuf-2.0;m;pangocairo-1.0;gio-2.0;cairo;pango-1.0;freetype;z;fontconfig;gobject-2.0;gmodule-2.0;glib-2.0
GTKMM_LIBRARY_DIRS:INTERNAL=
GTKMM_LIBS:INTERNAL=
GTKMM_LIBS_L:INTERNAL=
GTKMM_LIBS_OTHER:INTERNAL=
GTKMM_LIBS_PATHS:INTERNAL=
GTKMM_PREFIX:INTERNAL=/usr
GTKMM_STATIC_CFLAGS:INTERNAL=-I/usr/include/gtkmm-2.4;-I/usr/lib/gtkmm-2.4/include;-I/usr/include/glibmm-2.4;-I/usr/lib/glibmm-2.4/include;-I/usr/include/giomm-2.4;-I/usr/lib/giomm-2.4/include;-I/usr/include/gdkmm-2.4;-I/usr/lib/gdkmm-2.4/include;-I/usr/include/pangomm-1.4;-I/usr/include/atkmm-1.6;-I/usr/include/gtk-2.0;-I/usr/include/sigc++-2.0;-I/usr/lib/sigc++-2.0/include;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/lib/gtk-2.0/include;-I/usr/include/cairomm-1.0;-I/usr/include/pango-1.0;-I/usr/include/cairo;-I/usr/include/pixman-1;-I/usr/include/freetype2;-I/usr/include/libpng12;-I/usr/include/atk-1.0
GTKMM_STATIC_CFLAGS_I:INTERNAL=
GTKMM_STATIC_CFLAGS_OTHER:INTERNAL=
GTKMM_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/gtkmm-2.4;/usr/lib/gtkmm-2.4/include;/usr/include/glibmm-2.4;/usr/lib/glibmm-2.4/include;/usr/include/giomm-2.4;/usr/lib/giomm-2.4/include;/usr/include/gdkmm-2.4;/usr/lib/gdkmm-2.4/include;/usr/include/pangomm-1.4;/usr/include/atkmm-1.6;/usr/include/gtk-2.0;/usr/include/sigc++-2.0;/usr/lib/sigc++-2.0/include;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/lib/gtk-2.0/include;/usr/include/cairomm-1.0;/usr/include/pango-1.0;/usr/include/cairo;/usr/include/pixman-1;/usr/include/freetype2;/usr/include/libpng12;/usr/include/atk-1.0
GTKMM_STATIC_LDFLAGS:INTERNAL=-lgtkmm-2.4;-lgiomm-2.4;-lgdkmm-2.4;-latkmm-1.6;-lgtk-x11-2.0;-lpangomm-1.4;-lcairomm-1.0;-lglibmm-2.4;-lsigc-2.0;-lgdk-x11-2.0;-latk-1.0;-lpangoft2-1.0;-lXinerama;-lXi;-lXrandr;-lXcursor;-lXcomposite;-lXdamage;-lgdk_pixbuf-2.0;-ltiff;-ljpeg;-lpangocairo-1.0;-lgio-2.0;-lXext;-lXfixes;-lcairo;-lm;-lpixman-1;-lpng12;-lxcb-render-util;-lXrender;-lxcb-render;-lX11;-lpthread;-lxcb-xlib;-lxcb;-lXau;-lXdmcp;-lpango-1.0;-lfontconfig;-lexpat;-lfreetype;-lz;-lgobject-2.0;-lgmodule-2.0;-ldl;-lglib-2.0
GTKMM_STATIC_LDFLAGS_OTHER:INTERNAL=
GTKMM_STATIC_LIBDIR:INTERNAL=
GTKMM_STATIC_LIBRARIES:INTERNAL=gtkmm-2.4;giomm-2.4;gdkmm-2.4;atkmm-1.6;gtk-x11-2.0;pangomm-1.4;cairomm-1.0;glibmm-2.4;sigc-2.0;gdk-x11-2.0;atk-1.0;pangoft2-1.0;Xinerama;Xi;Xrandr;Xcursor;Xcomposite;Xdamage;gdk_pixbuf-2.0;tiff;jpeg;pangocairo-1.0;gio-2.0;Xext;Xfixes;cairo;m;pixman-1;png12;xcb-render-util;Xrender;xcb-render;X11;pthread;xcb-xlib;xcb;Xau;Xdmcp;pango-1.0;fontconfig;expat;freetype;z;gobject-2.0;gmodule-2.0;dl;glib-2.0
GTKMM_STATIC_LIBRARY_DIRS:INTERNAL=
GTKMM_STATIC_LIBS:INTERNAL=
GTKMM_STATIC_LIBS_L:INTERNAL=
GTKMM_STATIC_LIBS_OTHER:INTERNAL=
GTKMM_STATIC_LIBS_PATHS:INTERNAL=
GTKMM_VERSION:INTERNAL=2.14.1
GTKMM_gtkmm-2.4_INCLUDEDIR:INTERNAL=
GTKMM_gtkmm-2.4_LIBDIR:INTERNAL=
GTKMM_gtkmm-2.4_PREFIX:INTERNAL=
GTKMM_gtkmm-2.4_VERSION:INTERNAL=
GTK_CFLAGS:INTERNAL=-I/usr/include/gtk-2.0;-I/usr/lib/gtk-2.0/include;-I/usr/include/atk-1.0;-I/usr/include/cairo;-I/usr/include/pango-1.0;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/include/pixman-1;-I/usr/include/freetype2;-I/usr/include/libpng12
GTK_CFLAGS_I:INTERNAL=
GTK_CFLAGS_OTHER:INTERNAL=
GTK_FOUND:INTERNAL=1
GTK_INCLUDEDIR:INTERNAL=/usr/include
GTK_INCLUDE_DIRS:INTERNAL=/usr/include/gtk-2.0;/usr/lib/gtk-2.0/include;/usr/include/atk-1.0;/usr/include/cairo;/usr/include/pango-1.0;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/include/pixman-1;/usr/include/freetype2;/usr/include/libpng12
GTK_LDFLAGS:INTERNAL=-lgtk-x11-2.0;-lgdk-x11-2.0;-latk-1.0;-lpangoft2-1.0;-lgdk_pixbuf-2.0;-lm;-lpangocairo-1.0;-lgio-2.0;-lcairo;-lpango-1.0;-lfreetype;-lz;-lfontconfig;-lgobject-2.0;-lgmodule-2.0;-lglib-2.0
GTK_LDFLAGS_OTHER:INTERNAL=
GTK_LIBDIR:INTERNAL=/usr/lib
GTK_LIBRARIES:INTERNAL=gtk-x11-2.0;gdk-x11-2.0;atk-1.0;pangoft2-1.0;gdk_pixbuf-2.0;m;pangocairo-1.0;gio-2.0;cairo;pango-1.0;freetype;z;fontconfig;gobject-2.0;gmodule-2.0;glib-2.0
GTK_LIBRARY_DIRS:INTERNAL=
GTK_LIBS:INTERNAL=
GTK_LIBS_L:INTERNAL=
GTK_LIBS_OTHER:INTERNAL=
GTK_LIBS_PATHS:INTERNAL=
GTK_PREFIX:INTERNAL=/usr
GTK_STATIC_CFLAGS:INTERNAL=-I/usr/include/gtk-2.0;-I/usr/lib/gtk-2.0/include;-I/usr/include/atk-1.0;-I/usr/include/cairo;-I/usr/include/pango-1.0;-I/usr/include/glib-2.0;-I/usr/lib/glib-2.0/include;-I/usr/include/pixman-1;-I/usr/include/freetype2;-I/usr/include/libpng12
GTK_STATIC_CFLAGS_I:INTERNAL=
GTK_STATIC_CFLAGS_OTHER:INTERNAL=
GTK_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/gtk-2.0;/usr/lib/gtk-2.0/include;/usr/include/atk-1.0;/usr/include/cairo;/usr/include/pango-1.0;/usr/include/glib-2.0;/usr/lib/glib-2.0/include;/usr/include/pixman-1;/usr/include/freetype2;/usr/include/libpng12
GTK_STATIC_LDFLAGS:INTERNAL=-lgtk-x11-2.0;-lgdk-x11-2.0;-latk-1.0;-lpangoft2-1.0;-lXinerama;-lXi;-lXrandr;-lXcursor;-lXcomposite;-lXdamage;-lgdk_pixbuf-2.0;-ltiff;-ljpeg;-lpangocairo-1.0;-lgio-2.0;-lXext;-lXfixes;-lcairo;-lm;-lpixman-1;-lpng12;-lxcb-render-util;-lXrender;-lxcb-render;-lX11;-lpthread;-lxcb-xlib;-lxcb;-lXau;-lXdmcp;-lpango-1.0;-lfontconfig;-lexpat;-lfreetype;-lz;-lgobject-2.0;-lgmodule-2.0;-ldl;-lglib-2.0
GTK_STATIC_LDFLAGS_OTHER:INTERNAL=
GTK_STATIC_LIBDIR:INTERNAL=
GTK_STATIC_LIBRARIES:INTERNAL=gtk-x11-2.0;gdk-x11-2.0;atk-1.0;pangoft2-1.0;Xinerama;Xi;Xrandr;Xcursor;Xcomposite;Xdamage;gdk_pixbuf-2.0;tiff;jpeg;pangocairo-1.0;gio-2.0;Xext;Xfixes;cairo;m;pixman-1;png12;xcb-render-util;Xrender;xcb-render;X11;pthread;xcb-xlib;xcb;Xau;Xdmcp;pango-1.0;fontconfig;expat;freetype;z;gobject-2.0;gmodule-2.0;dl;glib-2.0
GTK_STATIC_LIBRARY_DIRS:INTERNAL=
GTK_STATIC_LIBS:INTERNAL=
GTK_STATIC_LIBS_L:INTERNAL=
GTK_STATIC_LIBS_OTHER:INTERNAL=
GTK_STATIC_LIBS_PATHS:INTERNAL=
GTK_VERSION:INTERNAL=2.14.4
GTK_gtk+-2.0_INCLUDEDIR:INTERNAL=
GTK_gtk+-2.0_LIBDIR:INTERNAL=
GTK_gtk+-2.0_PREFIX:INTERNAL=
GTK_gtk+-2.0_VERSION:INTERNAL=
//Advanced flag for variable: PKG_CONFIG_EXECUTABLE
PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1
__pkg_config_checked_GIO:INTERNAL=1
__pkg_config_checked_GIOMM:INTERNAL=1
__pkg_config_checked_GLIB2:INTERNAL=1
__pkg_config_checked_GLIBMM:INTERNAL=1
__pkg_config_checked_GTK:INTERNAL=1
__pkg_config_checked_GTKMM:INTERNAL=1

101
rtgui/CMakeLists.txt Executable file
View File

@@ -0,0 +1,101 @@
find_package(PkgConfig)
pkg_check_modules (GLIB2 glib-2.0>=2.16)
pkg_check_modules (GLIBMM glibmm-2.4>=2.16)
pkg_check_modules (GTK gtk+-2.0>=2.12)
pkg_check_modules (GTKMM gtkmm-2.4>=2.12)
pkg_check_modules (GIO gio-2.0>=2.16)
pkg_check_modules (GIOMM giomm-2.4>=2.12)
SET (BASESOURCEFILES
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
clipboard.cc thumbimageupdater.cc bqentryupdater.cc
coarsepanel.cc cacorrection.cc colorshift.cc hlrec.cc chmixer.cc
colorboost.cc resize.cc icmpanel.cc crop.cc shadowshighlights.cc
colordenoise.cc
exifpanel.cc
sharpening.cc
whitebalance.cc vignetting.cc rotate.cc distortion.cc
crophandler.cc curveeditor.cc dirbrowser.cc
filecatalog.cc
histogrampanel.cc history.cc imagearea.cc
imageareapanel.cc iptcpanel.cc lcurve.cc lumadenoise.cc main.cc
multilangmgr.cc mycurve.cc options.cc
preferences.cc profilepanel.cc saveasdlg.cc
saveformatpanel.cc splash.cc
thumbnail.cc tonecurve.cc toolbar.cc
guiutils.cc zoompanel.cc toolpanelcoord.cc
thumbbrowserentrybase.cc batchqueueentry.cc
batchqueue.cc lwbutton.cc lwbuttonset.cc
batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc
profilestore.cc partialpastedlg.cc)
IF (WIN32)
SET (EXTRA_LIBDIR "../lib")
SET (EXTRA_INCDIR "../winclude")
SET (EXTRA_SRC "windirmonitor.cc myicon.o")
SET (EXTRA_LIB "ws2_32")
include_directories (/usr/local/lib ../rtengine . ../rtexif ${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS}
${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS})
link_directories (. ../rtexif ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS}
${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS})
#set_target_properties (rth PROPERTIES LINK_FLAGS "-mwindows")
add_executable (rth windirmonitor.cc myicon.o ${BASESOURCEFILES})
ELSE (WIN32)
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
SET (EXTRA_INCDIR "../rawzor_lin32")
SET (EXTRA_LIBDIR "../rawzor_lin32")
ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 8)
SET (EXTRA_INCDIR "../rawzor_lin64")
SET (EXTRA_LIBDIR "../rawzor_lin64")
ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
include_directories (/usr/local/lib ../rtengine . ../rtexif ${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS}
${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS})
link_directories (. ../rtexif ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS}
${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS})
add_executable (rth ${BASESOURCEFILES})
ENDIF (WIN32)
set_target_properties (rth PROPERTIES COMPILE_FLAGS "-O3")
target_link_libraries (rth rtengine liblcms.a iptcdata libjpeg.a libpng.a libz.a libtiff.a ${EXTRA_LIB} gthread-2.0 gobject-2.0
${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES})
IF (WIN32)
install (FILES rth.exe DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
RENAME rt.exe)
install (FILES ../rawzor_win/rwz_sdk_s.dll DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
install (FILES ../options.win DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ
RENAME options)
ELSE (WIN32)
install (FILES rth DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
RENAME rt)
install (FILES ../options.lin DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ
RENAME options)
install (FILES ../rtstart DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
install (FILES ../rawzor_lin32/librwz_sdk.so DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ
RENAME rwz_sdk.so)
ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 8)
install (FILES ../rawzor_lin64/librwz_sdk.so DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../release
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ
RENAME rwz_sdk.so)
ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
ENDIF (WIN32)

BIN
rtgui/RT.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

273
rtgui/adjuster.cc Executable file
View File

@@ -0,0 +1,273 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <adjuster.h>
#include <sigc++/class_slot.h>
#include <math.h>
#include <multilangmgr.h>
extern Glib::ustring argv0;
int Adjuster::delay = 1000;
Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, bool editedcb) {
adjusterListener = NULL;
afterReset = false;
set_border_width (2);
hbox = Gtk::manage (new Gtk::HBox ());
label = Gtk::manage (new Gtk::Label (vlabel, Gtk::ALIGN_LEFT));
if (editedcb) {
editedCheckBox = new Gtk::CheckButton ();
editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) );
hbox->pack_start (*editedCheckBox);
}
else
editedCheckBox = NULL;
hbox->pack_start (*label);
reset = Gtk::manage (new Gtk::Button ());
reset->add (*Gtk::manage (new Gtk::Image (argv0+"/images/undo.png")));
reset->set_relief (Gtk::RELIEF_NONE);
reset->set_border_width (0);
reset->set_tooltip_text (M("ADJUSTER_RESET_TO_DEFAULT"));
hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0);
spin = Gtk::manage (new Gtk::SpinButton ());
spin->set_size_request (70, -1);
hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0);
reset->set_size_request (-1, spin->get_height());
slider = Gtk::manage (new Gtk::HScale ());
slider->set_draw_value (false);
pack_start (*hbox, false, false);
pack_start (*slider, false, false);
setLimits (vmin, vmax, vstep, vdefault);
defaultVal = shapeValue (vdefault);
editedState = defEditedState = Irrelevant;
sliderChange = slider->signal_value_changed().connect( sigc::mem_fun(*this, &Adjuster::sliderChanged) );
spinChange = spin->signal_value_changed().connect ( sigc::mem_fun(*this, &Adjuster::spinChanged), true);
reset->signal_clicked().connect( sigc::mem_fun(*this, &Adjuster::resetPressed) );
slider->set_update_policy (Gtk::UPDATE_CONTINUOUS);
show_all ();
}
Adjuster::~Adjuster () {
sliderChange.block (true);
spinChange.block (true);
delayConnection.block (true);
adjusterListener = NULL;
}
void Adjuster::setDefault (double def) {
defaultVal = shapeValue (def);
}
void Adjuster::setDefaultEditedState (EditedState eState) {
defEditedState = eState;
}
void Adjuster::resetPressed () {
if (editedState!=Irrelevant) {
editedState = defEditedState;
if (editedCheckBox) {
editedChange.block (true);
editedCheckBox->set_active (defEditedState==Edited);
editedChange.block (false);
}
refreshLabelStyle ();
}
afterReset = true;
slider->set_value (defaultVal);
}
double Adjuster::shapeValue (double a) {
return round(a*pow(10, digits)) / pow(10, digits);
}
void Adjuster::setLimits (double vmin, double vmax, double vstep, double vdefault) {
sliderChange.block (true);
spinChange.block (true);
for (digits=0; fabs(vstep*pow(10,digits)-floor(vstep*pow(10,digits)))>0.000000000001; digits++);
spin->set_digits (digits);
spin->set_increments (vstep, 2.0*vstep);
spin->set_range (vmin, vmax);
spin->set_value (shapeValue(vdefault));
slider->set_digits (digits);
slider->set_increments (vstep, 2.0*vstep);
slider->set_range (vmin, vmax);
slider->set_value (shapeValue(vdefault));
defaultVal = shapeValue (vdefault);
sliderChange.block (false);
spinChange.block (false);
}
void Adjuster::setAdjusterListener (AdjusterListener* alistener) {
adjusterListener = alistener;
}
void Adjuster::spinChanged () {
sliderChange.block (true);
slider->set_value (spin->get_value ());
sliderChange.block (false);
if (delay==0) {
if (adjusterListener!=NULL)
adjusterListener->adjusterChanged (this, spin->get_value ());
}
else
Glib::signal_idle().connect (sigc::mem_fun(*this, &Adjuster::notifyListener));
if (editedState==UnEdited) {
editedState = Edited;
if (editedCheckBox) {
editedChange.block (true);
editedCheckBox->set_active (true);
editedChange.block (false);
}
refreshLabelStyle ();
}
afterReset = false;
}
void Adjuster::sliderChanged () {
if (delayConnection.connected())
delayConnection.disconnect ();
spinChange.block (true);
spin->set_value (slider->get_value ());
spinChange.block (false);
if (delay==0) {
if (adjusterListener)
adjusterListener->adjusterChanged (this, spin->get_value ());
}
else
delayConnection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Adjuster::notifyListener), delay);
if (!afterReset && editedState==UnEdited) {
editedState = Edited;
if (editedCheckBox) {
editedChange.block (true);
editedCheckBox->set_active (true);
editedChange.block (false);
}
refreshLabelStyle ();
}
afterReset = false;
}
void Adjuster::setValue (double a) {
spinChange.block (true);
sliderChange.block (true);
spin->set_value (shapeValue (a));
slider->set_value (shapeValue (a));
sliderChange.block (false);
spinChange.block (false);
afterReset = false;
}
double Adjuster::getValue () {
return spin->get_value ();
}
bool Adjuster::notifyListener () {
gdk_threads_enter();
if (adjusterListener!=NULL)
adjusterListener->adjusterChanged (this, spin->get_value ());
gdk_threads_leave();
return false;
}
void Adjuster::setEnabled (bool enabled) {
spin->set_sensitive (enabled);
slider->set_sensitive (enabled);
}
void Adjuster::setEditedState (EditedState eState) {
if (editedState!=eState) {
if (editedCheckBox) {
editedChange.block (true);
editedCheckBox->set_active (eState==Edited);
editedChange.block (false);
}
editedState = eState;
refreshLabelStyle ();
}
}
EditedState Adjuster::getEditedState () {
if (editedState!=Irrelevant && editedCheckBox)
editedState = editedCheckBox->get_active () ? Edited : UnEdited;
return editedState;
}
void Adjuster::showEditedCB () {
if (!editedCheckBox) {
editedCheckBox = new Gtk::CheckButton ();
hbox->pack_start (*editedCheckBox, Gtk::PACK_SHRINK, 2);
hbox->reorder_child (*editedCheckBox, 0);
editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) );
}
}
void Adjuster::refreshLabelStyle () {
/* Glib::RefPtr<Gtk::Style> style = label->get_style ();
Pango::FontDescription fd = style->get_font ();
fd.set_weight (editedState==Edited ? Pango::WEIGHT_BOLD : Pango::WEIGHT_NORMAL);
style->set_font (fd);
label->set_style (style);
label->queue_draw ();*/
}
void Adjuster::editedToggled () {
if (adjusterListener)
adjusterListener->adjusterChanged (this, spin->get_value ());
}

83
rtgui/adjuster.h Executable file
View File

@@ -0,0 +1,83 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _ADJUSTER_H_
#define _ADJUSTER_H_
#include <gtkmm.h>
#include <editedstate.h>
class Adjuster;
class AdjusterListener {
public:
virtual void adjusterChanged (Adjuster* a, double newval) {}
};
class Adjuster : public Gtk::VBox {
protected:
Gtk::HBox* hbox;
Gtk::Label* label;
Gtk::HScale* slider;
Gtk::SpinButton* spin;
Gtk::Button* reset;
AdjusterListener* adjusterListener;
sigc::connection delayConnection;
sigc::connection spinChange;
sigc::connection sliderChange;
sigc::connection editedChange;
bool listenerReady;
double defaultVal;
EditedState editedState;
EditedState defEditedState;
int digits;
Gtk::CheckButton* editedCheckBox;
bool afterReset;
double shapeValue (double a);
void refreshLabelStyle ();
public:
static int delay;
Adjuster (Glib::ustring label, double vmin, double vmax, double vstep, double vdefault, bool editedCheckBox=false);
virtual ~Adjuster ();
void setAdjusterListener (AdjusterListener* alistener);
double getValue ();
void setValue (double a);
void setLimits (double vmin, double vmax, double vstep, double vdefault);
void setEnabled (bool enabled);
void setDefault (double def);
void setEditedState (EditedState eState);
EditedState getEditedState ();
void setDefaultEditedState (EditedState eState);
void showEditedCB ();
void spinChanged ();
void sliderChanged ();
bool notifyListener ();
void resetPressed ();
void editedToggled ();
};
#endif

403
rtgui/batchqueue.cc Executable file
View File

@@ -0,0 +1,403 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <batchqueue.h>
#include <glibmm.h>
#include <multilangmgr.h>
#include <filecatalog.h>
#include <batchqueuebuttonset.h>
#include <guiutils.h>
using namespace rtengine;
BatchQueue::BatchQueue () : processing(NULL), listener(NULL) {
int p = 0;
pmenu = new Gtk::Menu ();
pmenu->attach (*(cancel = new Gtk::MenuItem (M("FILEBROWSER_POPUPCANCELJOB"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(head = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVEHEAD"))), 0, 1, p, p+1); p++;
pmenu->attach (*(tail = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVEEND"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++;
pmenu->show_all ();
cancel->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::cancelItems), &selected));
head->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::headItems), &selected));
tail->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::tailItems), &selected));
selall->signal_activate().connect (sigc::mem_fun(*this, &BatchQueue::selectAll));
}
void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) {
pmenu->popup (3, 0);
}
void BatchQueue::addEntry (BatchQueueEntry* entry, bool head) {
entry->setParent (this);
entry->resize (options.thumbSize);
entry->selected = false;
if (!head)
fd.push_back (entry);
else {
std::vector<ThumbBrowserEntryBase*>::iterator pos;
for (pos=fd.begin(); pos!=fd.end(); pos++)
if (!(*pos)->processing) {
fd.insert (pos, entry);
break;
}
if (pos==fd.end())
fd.push_back (entry);
}
if (entry->thumbnail)
entry->thumbnail->imageEnqueued ();
BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (entry);
bqbs->setButtonListener (this);
entry->addButtonSet (bqbs);
arrangeFiles ();
queue_draw ();
notifyListener ();
}
int deleteitem (void* data) {
gdk_threads_enter ();
delete (BatchQueueEntry*)data;
gdk_threads_leave ();
return 0;
}
void BatchQueue::cancelItems (std::vector<ThumbBrowserEntryBase*>* items) {
for (int i=0; i<items->size(); i++) {
BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i];
if (entry->processing)
continue;
std::vector<ThumbBrowserEntryBase*>::iterator pos = std::find (fd.begin(), fd.end(), entry);
if (pos!=fd.end()) {
fd.erase (pos);
rtengine::ProcessingJob::destroy (entry->job);
if (entry->thumbnail)
entry->thumbnail->imageRemovedFromQueue ();
g_idle_add (deleteitem, entry);
}
}
for (int i=0; i<fd.size(); i++)
fd[i]->selected = false;
lastClicked = NULL;
selected.clear ();
redraw ();
notifyListener ();
}
void BatchQueue::headItems (std::vector<ThumbBrowserEntryBase*>* items) {
for (int i=items->size()-1; i>=0; i--) {
BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i];
if (entry->processing)
continue;
std::vector<ThumbBrowserEntryBase*>::iterator pos = std::find (fd.begin(), fd.end(), entry);
if (pos!=fd.end() && pos!=fd.begin()) {
fd.erase (pos);
// find the first item that is not under processing
for (pos=fd.begin(); pos!=fd.end(); pos++)
if (!(*pos)->processing) {
fd.insert (pos, entry);
break;
}
}
}
redraw ();
}
void BatchQueue::tailItems (std::vector<ThumbBrowserEntryBase*>* items) {
for (int i=0; i<items->size(); i++) {
BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i];
if (entry->processing)
continue;
std::vector<ThumbBrowserEntryBase*>::iterator pos = std::find (fd.begin(), fd.end(), entry);
if (pos!=fd.end()) {
fd.erase (pos);
fd.push_back (entry);
}
}
redraw ();
}
void BatchQueue::selectAll () {
lastClicked = NULL;
selected.clear ();
for (int i=0; i<fd.size(); i++) {
if (fd[i]->processing)
continue;
fd[i]->selected = true;
selected.push_back (fd[i]);
}
queue_draw ();
}
void BatchQueue::startProcessing () {
if (!processing && fd.size()>0) {
BatchQueueEntry* next = (BatchQueueEntry*)fd[0];
// tag it as processing
next->processing = true;
processing = next;
// remove from selection
if (processing->selected) {
std::vector<ThumbBrowserEntryBase*>::iterator pos = std::find (selected.begin(), selected.end(), processing);
if (pos!=selected.end())
selected.erase (pos);
processing->selected = false;
}
// remove button set
next->removeButtonSet ();
// start batch processing
rtengine::startBatchProcessing (next->job, this);
queue_draw ();
}
}
rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) {
gdk_threads_enter ();
// save image img
Glib::ustring fname;
SaveFormat saveFormat;
if (processing->outFileName=="") { // auto file name
fname = obtainFileName (processing->filename);
saveFormat = options.saveFormat;
}
else { // use the save-as filename with automatic completion for uniqueness
fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName));
saveFormat = processing->saveFormat;
}
printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str());
if (img && fname!="") {
int err = 0;
if (saveFormat.format=="tif")
err = img->saveAsTIFF (fname, saveFormat.tiffBits);
else if (saveFormat.format=="png")
err = img->saveAsPNG (fname, saveFormat.pngCompression, saveFormat.pngBits);
else if (saveFormat.format=="jpg")
err = img->saveAsJPEG (fname, saveFormat.jpegQuality);
img->free ();
if (!err && saveFormat.saveParams)
processing->params.save (removeExtension(fname) + ".pp2");
if (processing->thumbnail) {
processing->thumbnail->imageDeveloped ();
processing->thumbnail->imageRemovedFromQueue ();
if (listener)
listener->imageProcessingReady (processing->filename);
}
}
// delete from the queue
delete processing;
processing = NULL;
fd.erase (fd.begin());
// return next job
if (fd.size()==0) {
if (listener)
listener->queueEmpty ();
}
else if (listener && listener->canStartNext ()) {
BatchQueueEntry* next = (BatchQueueEntry*)fd[0];
// tag it as selected
next->processing = true;
processing = next;
// remove from selection
if (processing->selected) {
std::vector<ThumbBrowserEntryBase*>::iterator pos = std::find (selected.begin(), selected.end(), processing);
if (pos!=selected.end())
selected.erase (pos);
processing->selected = false;
}
// remove button set
next->removeButtonSet ();
}
redraw ();
notifyListener ();
gdk_threads_leave ();
return processing ? processing->job : NULL;
}
Glib::ustring BatchQueue::obtainFileName (const Glib::ustring& origFileName) {
std::vector<Glib::ustring> pa;
std::vector<Glib::ustring> da;
for (int i=0; i<origFileName.size(); i++) {
while ((i<origFileName.size()) && (origFileName[i]=='\\' || origFileName[i]=='/'))
i++;
if (i>=origFileName.size())
break;
Glib::ustring tok = "";
while ((i<origFileName.size()) && !(origFileName[i]=='\\' || origFileName[i]=='/'))
tok = tok + origFileName[i++];
da.push_back (tok);
}
if (origFileName[0]=='/' || origFileName[0]=='\\')
pa.push_back ("/" + da[0]);
else
pa.push_back (da[0]);
for (int i=1; i<da.size(); i++)
pa.push_back (pa[i-1] + "/" + da[i]);
// for (int i=0; i<da.size(); i++)
// printf ("da: %s\n", da[i].c_str());
// for (int i=0; i<pa.size(); i++)
// printf ("pa: %s\n", pa[i].c_str());
// extracting filebase
Glib::ustring filename;
int extpos = origFileName.size()-1;
for (; extpos>=0 && origFileName[extpos]!='.'; extpos--);
for (int k=extpos-1; k>=0 && origFileName[k]!='/' && origFileName[k]!='\\'; k--)
filename = origFileName[k] + filename;
// printf ("%d, |%s|\n", extpos, filename.c_str());
// constructing full output path
// printf ("path=|%s|\n", options.savePath.c_str());
Glib::ustring path="";
if (options.saveUsePathTemplate) {
int ix=0;
while (options.savePathTemplate[ix]!=0) {
if (options.savePathTemplate[ix]=='%') {
ix++;
if (options.savePathTemplate[ix]=='p') {
ix++;
int i = options.savePathTemplate[ix]-'0';
if (i<pa.size())
path = path + pa[pa.size()-i-1] + '/';
ix++;
}
else if (options.savePathTemplate[ix]=='d') {
ix++;
int i = options.savePathTemplate[ix]-'0';
if (i<da.size())
path = path + da[da.size()-i-1] + '/';
ix++;
}
else if (options.savePathTemplate[ix]=='f') {
path = path + filename;
}
}
else
path = path + options.savePathTemplate[ix];
ix++;
}
}
else
path = Glib::build_filename (options.savePathFolder, filename);
return autoCompleteFileName (path, options.saveFormat.format);
}
Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format) {
// separate filename and the path to the destination directory
Glib::ustring dstdir = Glib::path_get_dirname (fileName);
Glib::ustring dstfname = Glib::path_get_basename (fileName);
// create directory, if does not exist
if (g_mkdir_with_parents (dstdir.c_str(), 0755) )
return "";
for (int tries=0; tries<100; tries++) {
Glib::ustring fname;
if (tries==0)
fname = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), format);
else
fname = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, format);
if (!Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
return fname;
}
}
}
int bqredraw (void* p) {
gdk_threads_enter ();
((BatchQueue*)p)->redraw();
gdk_threads_leave ();
return 0;
}
void BatchQueue::setProgress (double p) {
if (processing)
processing->progress = p;
g_idle_add (bqredraw, this);
}
void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionData) {
std::vector<ThumbBrowserEntryBase*> bqe;
bqe.push_back ((BatchQueueEntry*)actionData);
if (actionCode==10) // cancel
cancelItems (&bqe);
else if (actionCode==8) // to head
headItems (&bqe);
else if (actionCode==9) // to tail
tailItems (&bqe);
}
struct NLParams {
BatchQueueListener* listener;
int qsize;
};
int bqnotifylistener (void* data) {
gdk_threads_enter ();
NLParams* params = (NLParams*)data;
params->listener->queueSizeChanged (params->qsize);
delete params;
gdk_threads_leave ();
return 0;
}
void BatchQueue::notifyListener () {
if (listener) {
NLParams* params = new NLParams;
params->listener = listener;
params->qsize = fd.size();
g_idle_add (bqnotifylistener, params);
}
}
void BatchQueue::redrawNeeded (LWButton* button) {
queue_draw ();
}

84
rtgui/batchqueue.h Executable file
View File

@@ -0,0 +1,84 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BATCHQUEUE_
#define _BATCHQUEUE_
#include <gtkmm.h>
#include <batchqueueentry.h>
#include <rtengine.h>
#include <options.h>
#include <lwbuttonset.h>
#include <thumbbrowserbase.h>
class BatchQueueListener {
public:
virtual void queueSizeChanged (int qsize) {}
virtual void imageProcessingReady (Glib::ustring fname) {}
virtual void queueEmpty () {}
virtual bool canStartNext () {}
};
class FileCatalog;
class BatchQueue : public ThumbBrowserBase,
public rtengine::BatchProcessingListener,
public LWButtonListener {
protected:
BatchQueueEntry* processing;
Glib::ustring nameTemplate;
Gtk::MenuItem* cancel;
Gtk::MenuItem* head;
Gtk::MenuItem* tail;
Gtk::MenuItem* selall;
Gtk::Menu* pmenu;
BatchQueueListener* listener;
Glib::ustring obtainFileName (const Glib::ustring& origFileName);
Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format);
public:
BatchQueue ();
void addEntry (BatchQueueEntry* entry, bool head=false);
void cancelItems (std::vector<ThumbBrowserEntryBase*>* items);
void headItems (std::vector<ThumbBrowserEntryBase*>* items);
void tailItems (std::vector<ThumbBrowserEntryBase*>* items);
void selectAll ();
void startProcessing ();
bool hasJobs () { return fd.size()>0; }
rtengine::ProcessingJob* imageReady (rtengine::IImage16* img);
void setProgress (double p);
void rightClicked (ThumbBrowserEntryBase* entry);
void buttonPressed (LWButton* button, int actionCode, void* actionData);
void redrawNeeded (LWButton* button);
void setBatchQueueListener (BatchQueueListener* l) { listener = l; }
void notifyListener ();
};
#endif

27
rtgui/batchqueuebuttonset Executable file
View File

@@ -0,0 +1,27 @@
#ifndef _THUMBNAILBUTTONSET_
#define _THUMBNAILBUTTONSET_
#include <lwbuttonset.h>
#include <gtkmm.h>
#include <thumbbrowserentry.h>
class ThumbBrowserEntry;
class ThumbnailButtonSet : public LWButtonSet {
static bool iconsLoaded;
public:
static Glib::RefPtr<Gdk::Pixbuf> rankIcon;
static Glib::RefPtr<Gdk::Pixbuf> gRankIcon;
static Glib::RefPtr<Gdk::Pixbuf> unRankIcon;
static Glib::RefPtr<Gdk::Pixbuf> trashIcon;
static Glib::RefPtr<Gdk::Pixbuf> unTrashIcon;
static Glib::RefPtr<Gdk::Pixbuf> processIcon;
ThumbnailButtonSet (ThumbBrowserEntry* myEntry);
void setRank (int stars);
void setInTrash (bool inTrash);
};
#endif

42
rtgui/batchqueuebuttonset.cc Executable file
View File

@@ -0,0 +1,42 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <batchqueuebuttonset.h>
#include <multilangmgr.h>
extern Glib::ustring argv0;
bool BatchQueueButtonSet::iconsLoaded = false;
Cairo::RefPtr<Cairo::ImageSurface> BatchQueueButtonSet::cancelIcon;
Cairo::RefPtr<Cairo::ImageSurface> BatchQueueButtonSet::headIcon;
Cairo::RefPtr<Cairo::ImageSurface> BatchQueueButtonSet::tailIcon;
BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) {
if (!iconsLoaded) {
cancelIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/deltags.png");
headIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/head.png");
tailIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/tail.png");
iconsLoaded = true;
}
add (new LWButton (headIcon, 8, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEHEAD")));
add (new LWButton (tailIcon, 9, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEEND")));
add (new LWButton (cancelIcon, 10, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPCANCELJOB")));
}

38
rtgui/batchqueuebuttonset.h Executable file
View File

@@ -0,0 +1,38 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BATCHQUEUEBUTTONSET_
#define _BATCHQUEUEBUTTONSET_
#include <lwbuttonset.h>
#include <gtkmm.h>
class BatchQueueEntry;
class BatchQueueButtonSet : public LWButtonSet {
static bool iconsLoaded;
public:
static Cairo::RefPtr<Cairo::ImageSurface> cancelIcon;
static Cairo::RefPtr<Cairo::ImageSurface> headIcon;
static Cairo::RefPtr<Cairo::ImageSurface> tailIcon;
BatchQueueButtonSet (BatchQueueEntry* myEntry);
};
#endif

156
rtgui/batchqueueentry.cc Executable file
View File

@@ -0,0 +1,156 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <batchqueueentry.h>
#include <thumbbrowserbase.h>
BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail)
: job(pjob), ThumbBrowserEntryBase(fname),
opreview(previmg), origpw(prevw), origph(prevh), progress(0), thumbnail(thumbnail),
outFileName("") {
params = pparams;
bqih = new BatchQueueEntryIdleHelper;
bqih->bqentry = this;
bqih->destroyed = false;
bqih->pending = 0;
if (thumbnail)
thumbnail->increaseRef ();
}
BatchQueueEntry::~BatchQueueEntry () {
batchQueueEntryUpdater.removeJobs (this);
delete [] opreview;
if (thumbnail)
thumbnail->decreaseRef ();
if (bqih->pending)
bqih->destroyed = true;
else
delete bqih;
}
void BatchQueueEntry::refreshThumbnailImage () {
if (!opreview)
return;
batchQueueEntryUpdater.add (opreview, origpw, origph, preh, this);
batchQueueEntryUpdater.process ();
}
void BatchQueueEntry::calcThumbnailSize () {
prew = preh * origpw / origph;
}
void BatchQueueEntry::drawProgressBar (Glib::RefPtr<Gdk::Window> win, Glib::RefPtr<Gdk::GC> gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {
if (processing) {
Cairo::RefPtr<Cairo::Context> cr = win->create_cairo_context();
cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
double px = x + w/6.0;
double pw = w*2.0/3.0;
double py = y + h/4.0;
double ph = h/2.0;
cr->move_to (px, py);
cr->line_to (px+pw, py);
cr->set_line_width (ph);
cr->set_line_cap (Cairo::LINE_CAP_ROUND);
cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p());
cr->stroke ();
cr->move_to (px, py);
cr->line_to (px+pw, py);
cr->set_line_width (ph*3.0/4.0);
cr->set_source_rgb (backgr.get_red_p(), backgr.get_green_p(), backgr.get_blue_p());
cr->stroke ();
cr->move_to (px, py);
cr->line_to (px+pw*progress, py);
cr->set_line_width (ph/2.0);
cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p());
cr->stroke ();
}
}
void BatchQueueEntry::removeButtonSet () {
delete buttonSet;
buttonSet = NULL;
}
struct bqupdate {
BatchQueueEntryIdleHelper* bqih;
guint8* img;
int w,h;
};
int bqeupdate (void* data) {
gdk_threads_enter ();
bqupdate* params = (bqupdate*)data;
BatchQueueEntryIdleHelper* bqih = params->bqih;
if (bqih->destroyed) {
if (bqih->pending == 1)
delete bqih;
else
bqih->pending--;
delete [] params->img;
delete params;
gdk_threads_leave ();
return 0;
}
bqih->bqentry->_updateImage (params->img, params->w, params->h);
bqih->pending--;
gdk_threads_leave ();
delete params;
return 0;
}
void BatchQueueEntry::updateImage (guint8* img, int w, int h) {
bqih->pending++;
bqupdate* param = new bqupdate ();
param->bqih = bqih;
param->img = img;
param->w = w;
param->h = h;
g_idle_add (bqeupdate, param);
}
void BatchQueueEntry::_updateImage (guint8* img, int w, int h) {
if (preh == h) {
prew = w;
preview = new guint8 [prew*preh*3];
memcpy (preview, img, prew*preh*3);
if (parent)
parent->redrawNeeded (this);
}
delete [] img;
}

66
rtgui/batchqueueentry.h Executable file
View File

@@ -0,0 +1,66 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BATCHQUEUEENTRY_
#define _BATCHQUEUEENTRY_
#include <gtkmm.h>
#include <rtengine.h>
#include <thumbbrowserentrybase.h>
#include <thumbnail.h>
#include <bqentryupdater.h>
class BatchQueueEntry;
struct BatchQueueEntryIdleHelper {
BatchQueueEntry* bqentry;
bool destroyed;
int pending;
};
class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener {
guint8* opreview;
int origpw, origph;
BatchQueueEntryIdleHelper* bqih;
public:
Thumbnail* thumbnail;
rtengine::ProcessingJob* job;
rtengine::procparams::ProcParams params;
double progress;
Glib::ustring outFileName;
SaveFormat saveFormat;
BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail=NULL);
~BatchQueueEntry ();
void refreshThumbnailImage ();
void calcThumbnailSize ();
void drawProgressBar (Glib::RefPtr<Gdk::Window> win, Glib::RefPtr<Gdk::GC> gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h);
void removeButtonSet ();
// bqentryupdatelistener interface
void updateImage (guint8* img, int w, int h);
void _updateImage (guint8* img, int w, int h); // inside gtk thread
};
#endif

241
rtgui/batchqueuepanel.cc Executable file
View File

@@ -0,0 +1,241 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <batchqueuepanel.h>
#include <options.h>
#include <preferences.h>
#include <multilangmgr.h>
#include <rtwindow.h>
BatchQueuePanel::BatchQueuePanel () {
batchQueue = new BatchQueue();
// construct batch queue panel with the extra "start" and "stop" button
Gtk::VBox* batchQueueButtonBox = Gtk::manage (new Gtk::VBox);
start = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STARTPROCESSING")));
stop = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STOPPROCESSING")));
autoStart = Gtk::manage (new Gtk::CheckButton ("Auto start"));
start->set_tooltip_text (M("FILEBROWSER_STARTPROCESSINGHINT"));
stop->set_tooltip_text (M("FILEBROWSER_STOPPROCESSINGHINT"));
autoStart->set_tooltip_text ("Start processing automatically when a new job arrives");
start->set_active (false);
stop->set_active (true);
autoStart->set_active (options.procQueueEnabled);
start->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-media-play"), Gtk::ICON_SIZE_BUTTON)));
startConnection = start->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::startBatchProc));
stop->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-media-stop"), Gtk::ICON_SIZE_BUTTON)));
stopConnection = stop->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::stopBatchProc));
batchQueueButtonBox->pack_start (*start, Gtk::PACK_SHRINK, 4);
batchQueueButtonBox->pack_start (*stop, Gtk::PACK_SHRINK, 4);
batchQueueButtonBox->pack_start (*autoStart, Gtk::PACK_SHRINK, 4);
// Output directory selection
fdir = Gtk::manage (new Gtk::Frame (M("PREFERENCES_OUTDIR")));
Gtk::VBox* odvb = Gtk::manage (new Gtk::VBox ());
odvb->set_border_width (4);
Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ());
useTemplate = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRTEMPLATE")+":"));
hb2->pack_start (*useTemplate, Gtk::PACK_SHRINK,4);
outdirTemplate = Gtk::manage (new Gtk::Entry ());
hb2->pack_start (*outdirTemplate);
odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 4);
outdirTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT"));
useTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT"));
Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ());
useFolder = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRFOLDER")+":"));
hb3->pack_start (*useFolder, Gtk::PACK_SHRINK,4);
outdirFolder = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_OUTDIRFOLDER"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER));
hb3->pack_start (*outdirFolder);
odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4);
outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT"));
useFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT"));
Gtk::RadioButton::Group g = useTemplate->get_group();
useFolder->set_group (g);
fdir->add (*odvb);
// Output file format selection
fformat = Gtk::manage (new Gtk::Frame (M("PREFERENCES_FILEFORMAT")));
saveFormatPanel = Gtk::manage (new SaveFormatPanel ());
fformat->add (*saveFormatPanel);
saveFormatPanel->init (options.saveFormat);
outdirTemplate->set_text (options.savePathTemplate);
if (Glib::file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR))
outdirFolder->set_filename (options.savePathFolder);
useTemplate->set_active (options.saveUsePathTemplate);
useFolder->set_active (!options.saveUsePathTemplate);
// setup signal handlers
outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions));
outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions));
useTemplate->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions));
useFolder->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions));
saveFormatPanel->setListener (this);
// setup button bar
topBox = Gtk::manage (new Gtk::HBox ());
pack_start (*topBox, Gtk::PACK_SHRINK);
topBox->pack_start (*batchQueueButtonBox, Gtk::PACK_SHRINK, 4);
topBox->pack_start (*fdir);
topBox->pack_start (*fformat, Gtk::PACK_SHRINK, 4);
// add middle browser area
Gtk::HBox* hBox = Gtk::manage (new Gtk::HBox ());
pack_start (*batchQueue);
// lower box with thumbnail zoom
bottomBox = Gtk::manage (new Gtk::HBox ());
pack_start (*bottomBox, Gtk::PACK_SHRINK);
// change thumbnail arrangement button
hAlignIcon = new Gtk::Image (argv0+"/images/horizontals.png");
vAlignIcon = new Gtk::Image (argv0+"/images/verticals.png");
hAlignIcon->show ();
vAlignIcon->show ();
chAlign = Gtk::manage (new Gtk::Button ());
chAlign->show ();
bottomBox->pack_end (*chAlign, Gtk::PACK_SHRINK);
chAlign->set_image (*hAlignIcon);
chAlign->set_relief (Gtk::RELIEF_NONE);
chAlign->signal_pressed().connect (sigc::mem_fun(*this, &BatchQueuePanel::arrangementButtonPressed));
chAlign->set_tooltip_text (M("FILEBROWSER_ARRANGEMENTHINT"));
bottomBox->pack_end (*Gtk::manage (new Gtk::VSeparator), Gtk::PACK_SHRINK, 4);
if (options.fbArrangement==1)
chAlign->set_image (*vAlignIcon);
else
chAlign->set_image (*hAlignIcon);
arrangementButtonPressed ();
// thumbnail zoom
Gtk::HBox* zoomBox = Gtk::manage (new Gtk::HBox ());
zoomBox->pack_start (*Gtk::manage (new Gtk::VSeparator), Gtk::PACK_SHRINK, 4);
Gtk::Label* zoomLabel = Gtk::manage (new Gtk::Label (Glib::ustring("<b>")+M("FILEBROWSER_THUMBSIZE")+":</b>"));
zoomLabel->set_use_markup (true);
zoomBox->pack_start (*zoomLabel, Gtk::PACK_SHRINK, 4);
zoomInButton = Gtk::manage (new Gtk::Button ());
zoomInButton->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-zoom-in"), Gtk::ICON_SIZE_SMALL_TOOLBAR)));
zoomInButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomIn));
zoomInButton->set_relief (Gtk::RELIEF_NONE);
zoomInButton->set_tooltip_text (M("FILEBROWSER_ZOOMINHINT"));
zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK);
zoomOutButton = Gtk::manage (new Gtk::Button ());
zoomOutButton->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-zoom-out"), Gtk::ICON_SIZE_SMALL_TOOLBAR)));
zoomOutButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomOut));
zoomOutButton->set_relief (Gtk::RELIEF_NONE);
zoomOutButton->set_tooltip_text (M("FILEBROWSER_ZOOMOUTHINT"));
zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK);
bottomBox->pack_end (*zoomBox, Gtk::PACK_SHRINK);
batchQueue->setBatchQueueListener (this);
show_all ();
}
void BatchQueuePanel::arrangementButtonPressed () {
if (chAlign->get_image()==hAlignIcon) {
chAlign->set_image (*vAlignIcon);
batchQueue->setArrangement (BatchQueue::TB_Vertical);
}
else {
chAlign->set_image (*hAlignIcon);
batchQueue->setArrangement (BatchQueue::TB_Horizontal);
}
}
void BatchQueuePanel::queueSizeChanged (int qsize) {
// TODO: write it somewhere
}
void BatchQueuePanel::imageProcessingReady (Glib::ustring fname) {
parent->imageDeveloped (fname);
}
void BatchQueuePanel::startBatchProc () {
stopConnection.block (true);
startConnection.block (true);
stop->set_active (false);
start->set_active (true);
stopConnection.block (false);
startConnection.block (false);
if (batchQueue->hasJobs()) {
fdir->set_sensitive (false);
fformat->set_sensitive (false);
batchQueue->startProcessing ();
}
else
stopBatchProc ();
}
void BatchQueuePanel::stopBatchProc () {
stopConnection.block (true);
startConnection.block (true);
stop->set_active (true);
start->set_active (false);
stopConnection.block (false);
startConnection.block (false);
}
void BatchQueuePanel::addBatchQueueJob (BatchQueueEntry* bqe, bool head) {
batchQueue->addEntry (bqe, head);
if (stop->get_active () && autoStart->get_active ())
startBatchProc ();
}
void BatchQueuePanel::queueEmpty () {
stopBatchProc ();
fdir->set_sensitive (true);
fformat->set_sensitive (true);
}
bool BatchQueuePanel::canStartNext () {
if (start->get_active ())
return true;
else {
fdir->set_sensitive (true);
fformat->set_sensitive (true);
return false;
}
}
void BatchQueuePanel::saveOptions () {
options.saveFormat = saveFormatPanel->getFormat ();
options.savePathTemplate = outdirTemplate->get_text();
options.savePathFolder = outdirFolder->get_filename();
options.saveUsePathTemplate = useTemplate->get_active();
options.procQueueEnabled = autoStart->get_active ();
}
void BatchQueuePanel::formatChanged () {
saveOptions ();
}

78
rtgui/batchqueuepanel.h Executable file
View File

@@ -0,0 +1,78 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BATCHQUEUEPANEL_
#define _BATCHQUEUEPANEL_
#include <gtkmm.h>
#include <batchqueue.h>
#include <saveformatpanel.h>
class RTWindow;
class BatchQueuePanel : public Gtk::VBox,
public BatchQueueListener,
public FormatChangeListener {
Gtk::Button* zoomInButton;
Gtk::Button* zoomOutButton;
Gtk::ToggleButton* start;
Gtk::ToggleButton* stop;
Gtk::CheckButton* autoStart;
sigc::connection startConnection;
sigc::connection stopConnection;
Gtk::Entry* outdirTemplate;
Gtk::FileChooserButton* outdirFolder;
Gtk::RadioButton* useTemplate;
Gtk::RadioButton* useFolder;
SaveFormatPanel* saveFormatPanel;
Gtk::Frame *fdir, *fformat;
Gtk::Image* hAlignIcon;
Gtk::Image* vAlignIcon;
Gtk::Button* chAlign;
RTWindow* parent;
BatchQueue* batchQueue;
Gtk::HBox* bottomBox;
Gtk::HBox* topBox;
public:
BatchQueuePanel ();
void setParent (RTWindow* p) { parent = p; }
void arrangementButtonPressed ();
void addBatchQueueJob (BatchQueueEntry* bqe, bool head=false);
// batchqueuelistener interface
void queueSizeChanged (int qsize);
void imageProcessingReady (Glib::ustring fname);
void queueEmpty ();
bool canStartNext ();
void startBatchProc ();
void stopBatchProc ();
void saveOptions ();
void formatChanged ();
};
#endif

295
rtgui/batchtoolpanelcoord.cc Executable file
View File

@@ -0,0 +1,295 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <multilangmgr.h>
#include <batchtoolpanelcoord.h>
#include <options.h>
#include <filepanel.h>
#include <procparamchangers.h>
using namespace rtengine::procparams;
BatchToolPanelCoordinator::BatchToolPanelCoordinator (FilePanel* parent) : ToolPanelCoordinator(), parent(parent) {
// remove exif panel and iptc panel
std::vector<ToolPanel*>::iterator epi = std::find (toolPanels.begin(), toolPanels.end(), exifpanel);
if (epi!=toolPanels.end())
toolPanels.erase (epi);
std::vector<ToolPanel*>::iterator ipi = std::find (toolPanels.begin(), toolPanels.end(), iptcpanel);
if (ipi!=toolPanels.end())
toolPanels.erase (ipi);
toolPanelNotebook->remove_page (*metadataPanel);
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->setBatchMode (true);
}
void BatchToolPanelCoordinator::selectionChanged (const std::vector<Thumbnail*>& selected) {
if (selected!=this->selected) {
closeSession ();
this->selected = selected;
selFileNames.clear ();
for (int i=0; i<selected.size(); i++)
selFileNames.push_back (selected[i]->getFileName ());
initSession ();
}
}
void BatchToolPanelCoordinator::closeSession (bool save) {
pparamsEdited.set (false);
for (int i=0; i<selected.size(); i++)
selected[i]->removeThumbnailListener (this);
if (somethingChanged && save) {
// read new values from the gui
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->write (&pparams, &pparamsEdited);
// combine with initial parameters and set
ProcParams newParams;
for (int i=0; i<selected.size(); i++) {
newParams = initialPP[i];
pparamsEdited.combine (newParams, pparams);
selected[i]->setProcParams (newParams, BATCHEDITOR, true);
}
}
for (int i=0; i<paramcListeners.size(); i++)
paramcListeners[i]->clearParamChanges ();
}
void BatchToolPanelCoordinator::initSession () {
somethingChanged = false;
initialPP.resize (selected.size());
for (int i=0; i<selected.size(); i++) {
initialPP[i] = selected[i]->getProcParams ();
selected[i]->applyAutoExp (initialPP[i]);
selected[i]->addThumbnailListener (this);
}
pparamsEdited.initFrom (initialPP);
/* curve->setAdjusterBehavior (false, false, false, false);
whitebalance->setAdjusterBehavior (false, false);
vignetting->setAdjusterBehavior (false);
rotate->setAdjusterBehavior (false);
distortion->setAdjusterBehavior (false);
cacorrection->setAdjusterBehavior (false, false);
colorshift->setAdjusterBehavior (false, false);
colorboost->setAdjusterBehavior (false);
lumadenoise->setAdjusterBehavior (false);
sharpening->setAdjusterBehavior (false);
shadowshighlights->setAdjusterBehavior (false, false, false);
*/
crop->setDimensions (100000, 100000);
/* if (selected.size()>0) {
pparams = selected[0]->getProcParams ();
for (int i=0; i<toolPanels.size(); i++) {
toolPanels[i]->setDefaults (&pparams, &pparamsEdited);
toolPanels[i]->read (&pparams, &pparamsEdited);
}
for (int i=0; i<paramcListeners.size(); i++)
paramcListeners[i]->procParamsChanged (&pparams, rtengine::EvPhotoLoaded, "batch processing", &pparamsEdited);
}
*/
if (selected.size()>0) {
pparams = selected[0]->getProcParams ();
coarse->initBatchBehavior ();
curve->setAdjusterBehavior (options.baBehav[0], options.baBehav[1], options.baBehav[2], options.baBehav[3]);
whitebalance->setAdjusterBehavior (options.baBehav[12], options.baBehav[13]);
vignetting->setAdjusterBehavior (options.baBehav[21]);
rotate->setAdjusterBehavior (options.baBehav[17]);
distortion->setAdjusterBehavior (options.baBehav[18]);
cacorrection->setAdjusterBehavior (options.baBehav[19], options.baBehav[20]);
colorshift->setAdjusterBehavior (options.baBehav[15], options.baBehav[16]);
colorboost->setAdjusterBehavior (options.baBehav[14]);
lumadenoise->setAdjusterBehavior (options.baBehav[11]);
sharpening->setAdjusterBehavior (options.baBehav[10]);
shadowshighlights->setAdjusterBehavior (options.baBehav[4], options.baBehav[5], options.baBehav[6]);
if (options.baBehav[0]) pparams.toneCurve.expcomp = 0;
if (options.baBehav[1]) pparams.toneCurve.brightness = 0;
if (options.baBehav[2]) pparams.toneCurve.black = 0;
if (options.baBehav[3]) pparams.toneCurve.contrast = 0;
if (options.baBehav[4]) pparams.sh.highlights = 0;
if (options.baBehav[5]) pparams.sh.shadows = 0;
if (options.baBehav[6]) pparams.sh.localcontrast = 0;
if (options.baBehav[10]) pparams.sharpening.amount = 0;
if (options.baBehav[11]) pparams.lumaDenoise.edgetolerance = 0;
if (options.baBehav[12]) pparams.wb.temperature = 0;
if (options.baBehav[13]) pparams.wb.green = 0;
if (options.baBehav[14]) pparams.colorBoost.amount = 0;
if (options.baBehav[15]) pparams.colorShift.a = 0;
if (options.baBehav[16]) pparams.colorShift.b = 0;
if (options.baBehav[17]) pparams.rotate.degree = 0;
if (options.baBehav[18]) pparams.distortion.amount = 0;
if (options.baBehav[19]) pparams.cacorrection.red = 0;
if (options.baBehav[20]) pparams.cacorrection.blue = 0;
if (options.baBehav[21]) pparams.vignetting.amount = 0;
for (int i=0; i<toolPanels.size(); i++) {
toolPanels[i]->setDefaults (&pparams, &pparamsEdited);
toolPanels[i]->read (&pparams, &pparamsEdited);
}
for (int i=0; i<paramcListeners.size(); i++)
paramcListeners[i]->procParamsChanged (&pparams, rtengine::EvPhotoLoaded, "batch processing", &pparamsEdited);
}
}
void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) {
if (selected.size()==0)
return;
somethingChanged = true;
pparamsEdited.set (false);
// read new values from the gui
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->write (&pparams, &pparamsEdited);
if (event==rtengine::EvAutoExp || event==rtengine::EvClip)
for (int i=0; i<selected.size(); i++) {
initialPP[i].toneCurve.autoexp = pparams.toneCurve.autoexp;
initialPP[i].toneCurve.clip = pparams.toneCurve.clip;
selected[i]->applyAutoExp (initialPP[i]);
}
// combine with initial parameters and set
ProcParams newParams;
for (int i=0; i<selected.size(); i++) {
newParams = initialPP[i];
pparamsEdited.combine (newParams, pparams);
selected[i]->setProcParams (newParams, BATCHEDITOR, false);
}
for (int i=0; i<paramcListeners.size(); i++)
paramcListeners[i]->procParamsChanged (&pparams, event, descr, &pparamsEdited);
}
void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green) {
if (selected.size()>0)
selected[0]->getAutoWB (temp, green);
}
void BatchToolPanelCoordinator::getCamWB (double& temp, double& green) {
if (selected.size()>0)
selected[0]->getCamWB (temp, green);
}
void BatchToolPanelCoordinator::optionsChanged () {
closeSession ();
initSession ();
}
void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt) {
if (whoChangedIt!=BATCHEDITOR) {
closeSession (false);
initSession ();
}
}
void BatchToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) {
pparams = *nparams;
if (paramsEdited)
pparamsEdited = *paramsEdited;
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->read (&pparams, &pparamsEdited);
somethingChanged = true;
// read new values from the gui
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->write (&pparams, &pparamsEdited);
// combine with initial parameters and set
ProcParams newParams;
for (int i=0; i<selected.size(); i++) {
newParams = initialPP[i];
pparamsEdited.combine (newParams, pparams);
selected[i]->setProcParams (newParams, BATCHEDITOR, false);
}
for (int i=0; i<paramcListeners.size(); i++)
paramcListeners[i]->procParamsChanged (&pparams, event, descr, &pparamsEdited);
}
void BatchToolPanelCoordinator::cropSelectionReady () {
toolBar->setTool (TMHand);
}
CropGUIListener* BatchToolPanelCoordinator::startCropEditing (Thumbnail* thm) {
if (thm) {
int w, h;
thm->getFinalSize (thm->getProcParams (), w, h);
printf ("final=%d %d\n", w, h);
crop->setDimensions (w, h);
}
return crop;
}
void BatchToolPanelCoordinator::rotateSelectionReady (double rotate_deg, Thumbnail* thm) {
toolBar->setTool (TMHand);
if (rotate_deg!=0.0)
rotate->straighten (rotate_deg);
}
void BatchToolPanelCoordinator::spotWBselected (int x, int y, Thumbnail* thm) {
// toolBar->setTool (TOOL_HAND);
if (x>0 && y>0 && thm) {
for (int i=0; i<selected.size(); i++)
if (selected[i]==thm) {
double temp;
double green;
thm->getSpotWB (x, y, whitebalance->getSize(), temp, green);
double otemp = initialPP[i].wb.temperature;
double ogreen = initialPP[i].wb.green;
if (options.baBehav[12])
temp = temp - otemp;
if (options.baBehav[13])
green = green - ogreen;
whitebalance->setWB (temp, green);
}
}
}

76
rtgui/batchtoolpanelcoord.h Executable file
View File

@@ -0,0 +1,76 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __BATCHTOOLPANELCCORD__
#define __BATCHTOOLPANELCCORD__
#include <thumbnail.h>
#include <toolpanelcoord.h>
#include <fileselectionchangelistener.h>
#include <rtengine.h>
#include <paramsedited.h>
#include <thumbnaillistener.h>
class FilePanel;
class BatchToolPanelCoordinator :
public ToolPanelCoordinator,
public FileSelectionChangeListener,
public ThumbnailListener
{
protected:
rtengine::procparams::ProcParams pparams;
ParamsEdited pparamsEdited;
std::vector<Thumbnail*> selected;
std::vector<Glib::ustring> selFileNames;
std::vector<rtengine::procparams::ProcParams> initialPP;
bool somethingChanged;
FilePanel* parent;
void closeSession (bool save=true);
void initSession ();
public:
BatchToolPanelCoordinator (FilePanel* parent);
// FileSelectionChangeListener interface
void selectionChanged (const std::vector<Thumbnail*>& selected);
// toolpanellistener interface
void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr);
// profilechangelistener interface
void profileChange (const rtengine::procparams::ProcParams* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL);
// wbprovider interface
void getAutoWB (double& temp, double& green);
void getCamWB (double& temp, double& green);
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
// imageareatoollistener interface
void spotWBselected (int x, int y, Thumbnail* thm=NULL);
void cropSelectionReady ();
void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL);
CropGUIListener* startCropEditing (Thumbnail* thm=NULL);
void optionsChanged ();
};
#endif

137
rtgui/bqentryupdater.cc Executable file
View File

@@ -0,0 +1,137 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <bqentryupdater.h>
#include <gtkmm.h>
#include <guiutils.h>
BatchQueueEntryUpdater batchQueueEntryUpdater;
BatchQueueEntryUpdater::BatchQueueEntryUpdater ()
: tostop(false), stopped(true), qMutex(NULL) {
}
void BatchQueueEntryUpdater::add (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener) {
if (!qMutex)
qMutex = new Glib::Mutex ();
qMutex->lock ();
// look up if an older version is in the queue
std::list<Job>::iterator i;
for (i=jqueue.begin(); i!=jqueue.end(); i++)
if (i->oimg==oimg && i->listener==listener) {
i->ow = ow;
i->oh = oh;
i->newh = newh;
i->listener = listener;
break;
}
// not found, create and append new job
if (i==jqueue.end ()) {
Job j;
j.oimg = oimg;
j.ow = ow;
j.oh = oh;
j.newh = newh;
j.listener = listener;
jqueue.push_back (j);
}
qMutex->unlock ();
}
void BatchQueueEntryUpdater::process () {
if (stopped)
#undef THREAD_PRIORITY_NORMAL
thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL);
}
void BatchQueueEntryUpdater::process_ () {
stopped = false;
tostop = false;
// TODO: process visible jobs first
while (!tostop && !jqueue.empty ()) {
qMutex->lock ();
Job current = jqueue.front ();
jqueue.pop_front ();
qMutex->unlock ();
if (current.listener) {
int neww = current.newh * current.ow / current.oh;
guint8* img = new guint8 [current.newh*neww*3];
thumbInterp (current.oimg, current.ow, current.oh, img, neww, current.newh);
current.listener->updateImage (img, neww, current.newh);
}
}
stopped = true;
}
void BatchQueueEntryUpdater::stop () {
if (stopped) {
tostop = true;
return; }
gdk_threads_leave();
tostop = true;
Glib::Thread::self()->yield();
if (!stopped)
thread->join ();
gdk_threads_enter();
}
void BatchQueueEntryUpdater::removeJobs () {
if (!qMutex)
return;
qMutex->lock ();
while (!jqueue.empty())
jqueue.pop_front ();
qMutex->unlock ();
}
void BatchQueueEntryUpdater::removeJobs (BQEntryUpdateListener* listener) {
if (!qMutex)
return;
qMutex->lock ();
bool ready = false;
while (!ready) {
ready = true;
std::list<Job>::iterator i;
for (i=jqueue.begin(); i!=jqueue.end(); i++)
if (i->listener == listener) {
jqueue.erase (i);
ready = false;
break;
}
}
qMutex->unlock ();
}
void BatchQueueEntryUpdater::terminate () {
stop ();
removeJobs ();
}

62
rtgui/bqentryupdater.h Executable file
View File

@@ -0,0 +1,62 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BQENTRYUPDATER_
#define _BQENTRYUPDATER_
#include <glibmm.h>
#include <rtengine.h>
#include <thumbnail.h>
class BQEntryUpdateListener {
public:
virtual void updateImage (guint8* img, int w, int h) {}
};
class BatchQueueEntryUpdater {
struct Job {
guint8* oimg;
int ow, oh, newh;
BQEntryUpdateListener* listener;
};
protected:
bool tostop;
bool stopped;
std::list<Job> jqueue;
Glib::Thread* thread;
Glib::Mutex* qMutex;
public:
BatchQueueEntryUpdater ();
void add (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener);
void process ();
void stop ();
void removeJobs ();
void removeJobs (BQEntryUpdateListener* listener);
void terminate ();
void process_ ();
};
extern BatchQueueEntryUpdater batchQueueEntryUpdater;
#endif

26
rtgui/browserfilter.cc Executable file
View File

@@ -0,0 +1,26 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <browserfilter.h>
BrowserFilter::BrowserFilter () : exifFilterEnabled (false) {
showTrash = true;
for (int i=0; i<6; i++)
showRanked[i] = true;
}

37
rtgui/browserfilter.h Executable file
View File

@@ -0,0 +1,37 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _BROWSERFILTER_
#define _BROWSERFILTER_
#include <exiffiltersettings.h>
class BrowserFilter {
public:
bool showRanked[6];
bool showTrash;
bool showNotTrash;
bool exifFilterEnabled;
ExifFilterSettings exifFilter;
BrowserFilter ();
};
#endif

138
rtgui/cacheimagedata.cc Executable file
View File

@@ -0,0 +1,138 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <cacheimagedata.h>
#include <vector>
#include <glib/gstdio.h>
CacheImageData::CacheImageData ()
: md5(""), supported(false), format(FT_Invalid), rank(0), inTrash(false), recentlySaved(false),
timeValid(false), exifValid(false) {
}
int CacheImageData::load (const Glib::ustring& fname) {
Glib::KeyFile keyFile;
try {
if (!keyFile.load_from_file (fname))
return 1;
if (keyFile.has_group ("General")) {
if (keyFile.has_key ("General", "MD5")) md5 = keyFile.get_string ("General", "MD5");
if (keyFile.has_key ("General", "Version")) version = keyFile.get_integer ("General", "Version");
if (keyFile.has_key ("General", "Supported")) supported = keyFile.get_boolean ("General", "Supported");
if (keyFile.has_key ("General", "Format")) format = (ThFileType)keyFile.get_integer ("General", "Format");
if (keyFile.has_key ("General", "Rank")) rank = keyFile.get_integer ("General", "Rank");
if (keyFile.has_key ("General", "InTrash")) inTrash = keyFile.get_boolean ("General", "InTrash");
if (keyFile.has_key ("General", "RecentlySaved")) recentlySaved = keyFile.get_boolean ("General", "RecentlySaved");
}
timeValid = keyFile.has_group ("DateTime");
if (timeValid) {
if (keyFile.has_key ("DateTime", "Year")) year = keyFile.get_integer ("DateTime", "Year");
if (keyFile.has_key ("DateTime", "Month")) month = keyFile.get_integer ("DateTime", "Month");
if (keyFile.has_key ("DateTime", "Day")) day = keyFile.get_integer ("DateTime", "Day");
if (keyFile.has_key ("DateTime", "Hour")) hour = keyFile.get_integer ("DateTime", "Hour");
if (keyFile.has_key ("DateTime", "Min")) min = keyFile.get_integer ("DateTime", "Min");
if (keyFile.has_key ("DateTime", "Sec")) sec = keyFile.get_integer ("DateTime", "Sec");
if (keyFile.has_key ("DateTime", "MSec")) msec = keyFile.get_integer ("DateTime", "MSec");
}
exifValid = false;
if (keyFile.has_group ("ExifInfo")) {
exifValid = true;
if (keyFile.has_key ("ExifInfo", "Valid")) exifValid = keyFile.get_boolean ("ExifInfo", "Valid");
if (exifValid) {
if (keyFile.has_key ("ExifInfo", "FNumber")) fnumber = keyFile.get_double ("ExifInfo", "FNumber");
if (keyFile.has_key ("ExifInfo", "Shutter")) shutter = keyFile.get_double ("ExifInfo", "Shutter");
if (keyFile.has_key ("ExifInfo", "FocalLen")) focalLen = keyFile.get_double ("ExifInfo", "FocalLen");
if (keyFile.has_key ("ExifInfo", "ISO")) iso = keyFile.get_integer ("ExifInfo", "ISO");
}
if (keyFile.has_key ("ExifInfo", "Lens")) lens = keyFile.get_string ("ExifInfo", "Lens");
if (keyFile.has_key ("ExifInfo", "Camera")) camera = keyFile.get_string ("ExifInfo", "Camera");
}
if (format==FT_Raw && keyFile.has_group ("ExtraRawInfo")) {
if (keyFile.has_key ("ExtraRawInfo", "ThumbImageType")) thumbImgType = keyFile.get_integer ("ExtraRawInfo", "ThumbImageType");
if (keyFile.has_key ("ExtraRawInfo", "ThumbImageOffset")) thumbOffset = keyFile.get_integer ("ExtraRawInfo", "ThumbImageOffset");
}
else {
rotate = 0;
thumbImgType = 0;
}
return 0;
}
catch (Glib::Error) {
return 1;
}
}
int CacheImageData::save (const Glib::ustring& fname) {
Glib::KeyFile keyFile;
try {
keyFile.load_from_file (fname);
} catch (...) {}
keyFile.set_string ("General", "MD5", md5);
keyFile.set_integer ("General", "Version", options.version);
keyFile.set_boolean ("General", "Supported", supported);
keyFile.set_integer ("General", "Format", format);
keyFile.set_integer ("General", "Rank", rank);
keyFile.set_boolean ("General", "InTrash", inTrash);
keyFile.set_boolean ("General", "RecentlySaved", recentlySaved);
if (timeValid) {
keyFile.set_integer ("DateTime", "Year", year);
keyFile.set_integer ("DateTime", "Month", month);
keyFile.set_integer ("DateTime", "Day", day);
keyFile.set_integer ("DateTime", "Hour", hour);
keyFile.set_integer ("DateTime", "Min", min);
keyFile.set_integer ("DateTime", "Sec", sec);
keyFile.set_integer ("DateTime", "MSec", msec);
}
keyFile.set_boolean ("ExifInfo", "Valid", exifValid);
if (exifValid) {
keyFile.set_double ("ExifInfo", "FNumber", fnumber);
keyFile.set_double ("ExifInfo", "Shutter", shutter);
keyFile.set_double ("ExifInfo", "FocalLen", focalLen);
keyFile.set_integer ("ExifInfo", "ISO", iso);
}
keyFile.set_string ("ExifInfo", "Lens", lens);
keyFile.set_string ("ExifInfo", "Camera", camera);
if (format==FT_Raw) {
keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType);
keyFile.set_integer ("ExtraRawInfo", "ThumbImageOffset", thumbOffset);
}
FILE *f = g_fopen (fname.c_str(), "wt");
if (!f)
return 1;
else {
fprintf (f, "%s", keyFile.to_data().c_str());
fclose (f);
return 0;
}
}

67
rtgui/cacheimagedata.h Executable file
View File

@@ -0,0 +1,67 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CACHEIMAGEDATA_
#define _CACHEIMAGEDATA_
#include <glibmm.h>
#include <options.h>
class CacheImageData {
public:
// basic informations
Glib::ustring md5;
int version;
bool supported;
ThFileType format;
char rank;
bool inTrash;
bool recentlySaved;
// time/date info
bool timeValid;
short year;
char month;
char day;
char hour;
char min;
char sec;
char msec;
// exif info
bool exifValid;
double fnumber;
double shutter;
double focalLen;
unsigned iso;
Glib::ustring lens;
Glib::ustring camera;
// additional info on raw images
int rotate;
int thumbImgType;
int thumbOffset;
CacheImageData ();
int load (const Glib::ustring& fname);
int save (const Glib::ustring& fname);
};
#endif

279
rtgui/cachemanager.cc Executable file
View File

@@ -0,0 +1,279 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <cachemanager.h>
#include <options.h>
#include <glib/gstdio.h>
#include <giomm.h>
#include <guiutils.h>
#include <procparamchangers.h>
CacheManager cacheMgr;
void CacheManager::init () {
openEntries.clear ();
baseDir = options.cacheBaseDir;
if (!Glib::file_test (baseDir, Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (baseDir.c_str(), 511);
if (!Glib::file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")).c_str(), 511);
if (!Glib::file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")).c_str(), 511);
if (!Glib::file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")).c_str(), 511);
if (!Glib::file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")).c_str(), 511);
if (!Glib::file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR))
g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")).c_str(), 511);
}
Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) {
Thumbnail* res = NULL;
std::map<std::string, Thumbnail*>::iterator r = openEntries.find (fname);
// if it is open, return it
if (r!=openEntries.end()) {
r->second->increaseRef ();
return r->second;
}
// compute the md5
std::string md5 = getMD5 (fname);
if (md5=="")
return NULL;
// build path name
Glib::ustring cfname = getCacheFileName ("data", fname, md5) + ".txt";
// let's see if we have it in the cache
if (Glib::file_test (cfname, Glib::FILE_TEST_EXISTS)) {
CacheImageData* cfs = new CacheImageData ();
int e = cfs->load (cfname);
if (!e && cfs->supported==true)
res = new Thumbnail (this, fname, cfs);
if (res && !res->isSupported ()) {
delete res;
res = NULL;
}
delete cfs;
}
// if not, create a new one
if (!res) {
res = new Thumbnail (this, fname, md5);
if (!res->isSupported ()) {
delete res;
res = NULL;
}
}
if (res)
openEntries[fname] = res;
return res;
}
void CacheManager::deleteEntry (const Glib::ustring& fname) {
// check if it is opened
std::map<std::string, Thumbnail*>::iterator r = openEntries.find (fname);
// if it is open, dont delete it
if (r!=openEntries.end()) {
std::string md5 = r->second->getMD5 ();
r->second->decreaseRef ();
// if in the editor, the thumbnail still exists. If not, delete it:
r = openEntries.find (fname);
if (r==openEntries.end() && md5!="") {
::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str());
::g_remove ((getCacheFileName ("profiles", fname, md5) + ".pp2").c_str());
::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str());
::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str());
::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str());
::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str());
}
}
else {
std::string md5 = getMD5 (fname);
if (md5!="") {
::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str());
::g_remove ((getCacheFileName ("profiles", fname, md5) + ".pp2").c_str());
::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str());
::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str());
::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str());
::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str());
}
}
}
void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) {
std::string newmd5 = getMD5 (newfilename);
::g_rename ((getCacheFileName ("profiles", oldfilename, oldmd5) + ".pp2").c_str(), (getCacheFileName ("profiles", newfilename, newmd5) + ".pp2").c_str());
::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".cust").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".cust").c_str());
::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".jpg").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".jpg").c_str());
::g_rename ((getCacheFileName ("aehistograms", oldfilename, oldmd5)).c_str(), (getCacheFileName ("aehistograms", newfilename, newmd5)).c_str());
::g_rename ((getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc").c_str(), (getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc").c_str());
::g_rename ((getCacheFileName ("data", oldfilename, oldmd5) + ".txt").c_str(), (getCacheFileName ("data", newfilename, newmd5) + ".txt").c_str());
// check if it is opened
std::map<std::string, Thumbnail*>::iterator r = openEntries.find (oldfilename);
// if it is open, update md5
if (r!=openEntries.end()) {
Thumbnail* t = r->second;
openEntries.erase (r);
t->setFileName (newfilename);
openEntries[newfilename] = t;
t->updateCache ();
t->reSaveThumbnail ();
}
}
void CacheManager::closeThumbnail (Thumbnail* t) {
t->updateCache ();
std::map<std::string, Thumbnail*>::iterator r = openEntries.find (t->getFileName());
if (r!=openEntries.end())
openEntries.erase (r);
delete t;
}
void CacheManager::closeCache () {
applyCacheSizeLimitation ();
}
void CacheManager::clearAll () {
deleteDir ("images");
deleteDir ("aehistograms");
deleteDir ("embprofiles");
deleteDir ("profiles");
deleteDir ("data");
// re-generate thumbnail images and clear profiles of open thumbnails
std::map<std::string, Thumbnail*>::iterator i;
for (i=openEntries.begin(); i!=openEntries.end(); i++) {
i->second->clearProcParams (CACHEMGR);
i->second->generateThumbnailImage ();
i->second->updateCache ();
}
}
void CacheManager::clearThumbImages () {
deleteDir ("images");
deleteDir ("aehistograms");
deleteDir ("embprofiles");
// re-generate thumbnail images of open thumbnails
std::map<std::string, Thumbnail*>::iterator i;
for (i=openEntries.begin(); i!=openEntries.end(); i++)
i->second->generateThumbnailImage ();
}
void CacheManager::clearProfiles () {
deleteDir ("profiles");
// clear profiles of open thumbnails
std::map<std::string, Thumbnail*>::iterator i;
for (i=openEntries.begin(); i!=openEntries.end(); i++)
i->second->clearProcParams (CACHEMGR);
}
void CacheManager::deleteDir (const Glib::ustring& dirName) {
try {
Glib::Dir* dir = new Glib::Dir (Glib::build_filename (baseDir, dirName));
for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i)
::g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i).c_str());
delete dir;
}
catch (const Glib::FileError& fe) {
}
}
std::string CacheManager::getMD5 (const Glib::ustring& fname) {
try {
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path (fname);
if (!file)
return "";
Glib::RefPtr<Gio::FileInfo> info = file->query_info();
if (!info)
return "";
else
return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, Glib::ustring::compose ("%1%2", fname, info->get_size()));
}
catch (...) {
return "";
}
}
Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5) {
Glib::ustring cfn = Glib::build_filename (baseDir, subdir);
Glib::ustring cname = Glib::path_get_basename (fname) + "." + md5;
return Glib::build_filename (cfn, cname);
}
class FileMTimeInfo {
public:
Glib::ustring fname;
Glib::TimeVal mtime;
FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {}
bool operator<(const FileMTimeInfo& other) const { return mtime<other.mtime; }
};
void CacheManager::applyCacheSizeLimitation () {
std::vector<FileMTimeInfo> flist;
try {
Glib::ustring dataDir = Glib::build_filename (baseDir, "data");
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (dataDir);
if (!dir)
return;
Glib::RefPtr<Gio::FileEnumerator> dirList = dir->enumerate_children ();
if (!dirList)
return;
for (Glib::RefPtr<Gio::FileInfo> info = dirList->next_file(); info; info = dirList->next_file())
flist.push_back (FileMTimeInfo (removeExtension(info->get_name()), info->modification_time()));
if (flist.size() > options.maxCacheEntries) {
std::sort (flist.begin(), flist.end());
while (flist.size() > options.maxCacheEntries) {
::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt").c_str());
::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust").c_str());
::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg").c_str());
::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)).c_str());
::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc").c_str());
// ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + ".pp2").c_str());
flist.erase (flist.begin());
}
}
}
catch (Glib::Exception& ex) {
printf ("%s\n", ex.what().c_str());
}
}

64
rtgui/cachemanager.h Executable file
View File

@@ -0,0 +1,64 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CACHEMANAGER_
#define _CACHEMANAGER_
#include <string>
#include <map>
#include <glibmm.h>
#include <thumbnail.h>
#include <stdio.h>
class Thumbnail;
class CacheManager {
std::map<std::string, Thumbnail*> openEntries;
Glib::ustring baseDir;
void deleteDir (const Glib::ustring& dirName);
public:
CacheManager () {}
void init ();
Thumbnail* getEntry (const Glib::ustring& fname);
void deleteEntry (const Glib::ustring& fname);
void renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename);
void closeThumbnail (Thumbnail* t);
const Glib::ustring& getBaseDir () { return baseDir; }
void closeCache ();
static std::string getMD5 (const Glib::ustring& fname);
void clearAll ();
void clearThumbImages ();
void clearProfiles ();
void applyCacheSizeLimitation ();
Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5);
};
extern CacheManager cacheMgr;
#endif

103
rtgui/cacorrection.cc Executable file
View File

@@ -0,0 +1,103 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <cacorrection.h>
#include <iomanip>
using namespace rtengine;
using namespace rtengine::procparams;
CACorrection::CACorrection () : valaAdd(false), valbAdd(false) {
red = Gtk::manage (new Adjuster (M("TP_CACORRECTION_RED"), -0.005, 0.005, 0.0001, 0));
red->setAdjusterListener (this);
blue = Gtk::manage (new Adjuster (M("TP_CACORRECTION_BLUE"), -0.005, 0.005, 0.0001, 0));
blue->setAdjusterListener (this);
pack_start (*red);
pack_start (*blue);
show_all();
}
void CACorrection::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
red->setEditedState (pedited->cacorrection.red ? Edited : UnEdited);
blue->setEditedState (pedited->cacorrection.blue ? Edited : UnEdited);
}
red->setValue (pp->cacorrection.red);
blue->setValue (pp->cacorrection.blue);
enableListener ();
}
void CACorrection::write (ProcParams* pp, ParamsEdited* pedited) {
pp->cacorrection.red = red->getValue ();
pp->cacorrection.blue = blue->getValue ();
if (pedited) {
pedited->cacorrection.red = red->getEditedState ();
pedited->cacorrection.blue = blue->getEditedState ();
}
}
void CACorrection::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
red->setDefault (defParams->cacorrection.red);
blue->setDefault (defParams->cacorrection.blue);
if (pedited) {
red->setDefaultEditedState (pedited->cacorrection.red ? Edited : UnEdited);
blue->setDefaultEditedState (pedited->cacorrection.blue ? Edited : UnEdited);
}
else {
red->setDefaultEditedState (Irrelevant);
blue->setDefaultEditedState (Irrelevant);
}
}
void CACorrection::adjusterChanged (Adjuster* a, double newval) {
if (listener)
listener->panelChanged (EvCACorr, Glib::ustring::compose ("%1=%3\n%2=%4", M("TP_CACORRECTION_RED"), M("TP_CACORRECTION_BLUE"), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), red->getValue()), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), blue->getValue())));
}
void CACorrection::setAdjusterBehavior (bool baadd, bool bbadd) {
if (!valaAdd && baadd || valaAdd && !baadd)
red->setLimits (-0.005, 0.005, 0.0001, 0);
if (!valbAdd && bbadd || valbAdd && !bbadd)
blue->setLimits (-0.005, 0.005, 0.0001, 0);
valaAdd = baadd;
valbAdd = bbadd;
}
void CACorrection::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
red->showEditedCB ();
blue->showEditedCB ();
}

46
rtgui/cacorrection.h Executable file
View File

@@ -0,0 +1,46 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CACORRECTION_H_
#define _CACORRECTION_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class CACorrection : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster* red;
Adjuster* blue;
bool valaAdd, valbAdd;
public:
CACorrection ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void setAdjusterBehavior (bool baadd, bool bbadd);
};
#endif

151
rtgui/chmixer.cc Executable file
View File

@@ -0,0 +1,151 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <chmixer.h>
using namespace rtengine;
using namespace rtengine::procparams;
ChMixer::ChMixer () {
Gtk::Label* rlabel = Gtk::manage (new Gtk::Label ());
rlabel->set_markup (Glib::ustring("<span foreground=\"red\"><b>") + M("TP_CHMIXER_RED") + Glib::ustring(":</b></span>"));
red[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 100));
red[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 0));
red[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 0));
Gtk::HSeparator* rsep = Gtk::manage (new Gtk::HSeparator ());
pack_start (*rlabel);
for (int i=0; i<3; i++)
pack_start (*red[i]);
pack_start (*rsep);
Gtk::Label* glabel = Gtk::manage (new Gtk::Label ());
glabel->set_markup (Glib::ustring("<span foreground=\"darkgreen\"><b>") + M("TP_CHMIXER_GREEN") + Glib::ustring(":</b></span>"));
green[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 0));
green[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 100));
green[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 0));
Gtk::HSeparator* gsep = Gtk::manage (new Gtk::HSeparator ());
pack_start (*glabel);
for (int i=0; i<3; i++)
pack_start (*green[i]);
pack_start (*gsep);
Gtk::Label* blabel = Gtk::manage (new Gtk::Label ());
blabel->set_markup (Glib::ustring("<span foreground=\"blue\"><b>") + M("TP_CHMIXER_BLUE") + Glib::ustring(":</b></span>"));
blue[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 0));
blue[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 0));
blue[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 100));
for (int i=0; i<3; i++) {
red[i]->setAdjusterListener (this);
green[i]->setAdjusterListener (this);
blue[i]->setAdjusterListener (this);
}
pack_start (*blabel);
for (int i=0; i<3; i++)
pack_start (*blue[i]);
show_all();
}
void ChMixer::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited)
for (int i=0; i<3; i++) {
red[i]->setEditedState (pedited->chmixer.red[i] ? Edited : UnEdited);
green[i]->setEditedState (pedited->chmixer.green[i] ? Edited : UnEdited);
blue[i]->setEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited);
}
for (int i=0; i<3; i++) {
red[i]->setValue (pp->chmixer.red[i]);
green[i]->setValue (pp->chmixer.green[i]);
blue[i]->setValue (pp->chmixer.blue[i]);
}
enableListener ();
}
void ChMixer::write (ProcParams* pp, ParamsEdited* pedited) {
for (int i=0; i<3; i++) {
pp->chmixer.red[i] = (int) red[i]->getValue ();
pp->chmixer.green[i] = (int) green[i]->getValue ();
pp->chmixer.blue[i] = (int) blue[i]->getValue ();
}
if (pedited)
for (int i=0; i<3; i++) {
pedited->chmixer.red[i] = red[i]->getEditedState ();
pedited->chmixer.green[i] = green[i]->getEditedState ();
pedited->chmixer.blue[i] = blue[i]->getEditedState ();
}
}
void ChMixer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
for (int i=0; i<3; i++) {
red[i]->setDefault (defParams->chmixer.red[i]);
green[i]->setDefault (defParams->chmixer.green[i]);
blue[i]->setDefault (defParams->chmixer.blue[i]);
}
if (pedited)
for (int i=0; i<3; i++) {
red[i]->setDefaultEditedState (pedited->chmixer.red[i] ? Edited : UnEdited);
green[i]->setDefaultEditedState (pedited->chmixer.green[i] ? Edited : UnEdited);
blue[i]->setDefaultEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited);
}
else
for (int i=0; i<3; i++) {
red[i]->setDefaultEditedState (Irrelevant);
green[i]->setDefaultEditedState (Irrelevant);
blue[i]->setDefaultEditedState (Irrelevant);
}
}
void ChMixer::adjusterChanged (Adjuster* a, double newval) {
if (listener) {
Glib::ustring descr = Glib::ustring::compose ("R=%1,%2,%3\nG=%4,%5,%6\nB=%7,%8,%9",
(int)red[0]->getValue(), (int)red[1]->getValue(), (int)red[2]->getValue(),
(int)green[0]->getValue(), (int)green[1]->getValue(), (int)green[2]->getValue(),
(int)blue[0]->getValue(), (int)blue[1]->getValue(), (int)blue[2]->getValue());
listener->panelChanged (EvChMixer, descr);
}
}
void ChMixer::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
for (int i=0; i<3; i++) {
red[i]->showEditedCB ();
green[i]->showEditedCB ();
blue[i]->showEditedCB ();
}
}

45
rtgui/chmixer.h Executable file
View File

@@ -0,0 +1,45 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CHMIXER_H_
#define _CHMIXER_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class ChMixer : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster *red[3];
Adjuster *green[3];
Adjuster *blue[3];
public:
ChMixer ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
};
#endif

21
rtgui/clipboard.cc Executable file
View File

@@ -0,0 +1,21 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <clipboard.h>
Clipboard clipboard;

44
rtgui/clipboard.h Executable file
View File

@@ -0,0 +1,44 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CLIPBOARD_
#define _CLIPBOARD_
#include <vector>
#include <rtengine.h>
class Clipboard {
bool _hasIPTC;
std::vector<rtengine::procparams::IPTCPair> iptc;
bool _hasProcParams;
rtengine::procparams::ProcParams procParams;
public:
void setIPTC (const std::vector<rtengine::procparams::IPTCPair>& iptcc) { iptc = iptcc; _hasIPTC = true;}
const std::vector<rtengine::procparams::IPTCPair>& getIPTC () { return iptc; }
bool hasIPTC () { return _hasIPTC; }
void setProcParams (const rtengine::procparams::ProcParams& pparams) { procParams = pparams; _hasProcParams = true; }
const rtengine::procparams::ProcParams& getProcParams () { return procParams; }
bool hasProcParams () { return _hasProcParams; }
};
extern Clipboard clipboard;
#endif

148
rtgui/coarsepanel.cc Executable file
View File

@@ -0,0 +1,148 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <coarsepanel.h>
extern Glib::ustring argv0;
using namespace rtengine;
using namespace rtengine::procparams;
CoarsePanel::CoarsePanel () : ToolPanel () {
degree = 0;
Gtk::Image* rotateli = Gtk::manage (new Gtk::Image (argv0+"/images/stock-rotate-270-16.png"));
rotate_left = Gtk::manage (new Gtk::Button ());
rotate_left->add (*rotateli);
rotate_left->set_relief(Gtk::RELIEF_NONE);
pack_start (*rotate_left);
Gtk::Image* rotateri = Gtk::manage (new Gtk::Image (argv0+"/images/stock-rotate-90-16.png"));
rotate_right = Gtk::manage (new Gtk::Button ());
rotate_right->add (*rotateri);
rotate_right->set_relief(Gtk::RELIEF_NONE);
pack_start (*rotate_right);
Gtk::Image* fliphi = Gtk::manage (new Gtk::Image (argv0+"/images/stock-flip-horizontal-16.png"));
hflip = Gtk::manage (new Gtk::ToggleButton ());
hflip->add (*fliphi);
hflip->set_relief(Gtk::RELIEF_NONE);
pack_start (*hflip);
Gtk::Image* flipvi = Gtk::manage (new Gtk::Image (argv0+"/images/stock-flip-vertical-16.png"));
vflip = Gtk::manage (new Gtk::ToggleButton ());
vflip->add (*flipvi);
vflip->set_relief(Gtk::RELIEF_NONE);
pack_start (*vflip);
rotate_left->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_ROTLEFT"));
rotate_right->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_ROTRIGHT"));
vflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_VFLIP"));
hflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_HFLIP"));
rotate_left->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateLeft) );
rotate_right->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateRight) );
hflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipHorizontal) );
vflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipVertical) );
show_all_children ();
}
void CoarsePanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
degree = 0;
hflip->set_active (pedited->coarse.hflip ? pp->coarse.hflip : false);
vflip->set_active (pedited->coarse.vflip ? pp->coarse.vflip : false);
oldhflip = pp->coarse.hflip;
oldvflip = pp->coarse.vflip;
}
else {
degree = pp->coarse.rotate;
hflip->set_active (pp->coarse.hflip);
vflip->set_active (pp->coarse.vflip);
}
enableListener ();
}
void CoarsePanel::write (ProcParams* pp, ParamsEdited* pedited) {
pp->coarse.rotate = degree;
if (pedited) {
pedited->coarse.rotate = degree!=0;
pedited->coarse.hflip = oldhflip != hflip->get_active ();
pedited->coarse.vflip = oldvflip != vflip->get_active ();
pp->coarse.hflip = oldhflip != hflip->get_active ();
pp->coarse.vflip = oldvflip != vflip->get_active ();
}
else {
pp->coarse.hflip = hflip->get_active ();
pp->coarse.vflip = vflip->get_active ();
}
}
void CoarsePanel::initBatchBehavior () {
disableListener ();
degree = 0;
hflip->set_active (false);
vflip->set_active (false);
enableListener ();
}
void CoarsePanel::rotateLeft () {
degree = (degree + 270) % 360;
if (listener)
listener->panelChanged (EvCTRotate, Glib::ustring::format (degree));
}
void CoarsePanel::rotateRight () {
degree = (degree + 90) % 360;
if (listener)
listener->panelChanged (EvCTRotate, Glib::ustring::format (degree));
}
void CoarsePanel::flipHorizontal () {
if (listener) {
if (hflip->get_active ())
listener->panelChanged (EvCTHFlip, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvCTHFlip, M("GENERAL_DISABLED"));
}
}
void CoarsePanel::flipVertical () {
if (listener) {
if (vflip->get_active ())
listener->panelChanged (EvCTVFlip, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvCTVFlip, M("GENERAL_DISABLED"));
}
}

49
rtgui/coarsepanel.h Executable file
View File

@@ -0,0 +1,49 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __COARSEPANEL__
#define __COARSEPANEL__
#include <gtkmm.h>
#include <toolpanel.h>
class CoarsePanel : public Gtk::HBox, public ToolPanel {
protected:
Gtk::Button* rotate_left;
Gtk::Button* rotate_right;
Gtk::ToggleButton* hflip;
Gtk::ToggleButton* vflip;
int degree;
bool oldhflip, oldvflip;
public:
CoarsePanel ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void initBatchBehavior ();
void rotateLeft ();
void rotateRight ();
void flipHorizontal ();
void flipVertical ();
};
#endif

191
rtgui/colorboost.cc Executable file
View File

@@ -0,0 +1,191 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <colorboost.h>
#include <iomanip>
#include <guiutils.h>
using namespace rtengine;
using namespace rtengine::procparams;
ColorBoost::ColorBoost () : ToolPanel(), cbAdd(false) {
colorboost = new Adjuster (M("TP_COLORBOOST_AMOUNT"), -100, 300, 1, 0);
pack_start (*colorboost);
pack_start (*Gtk::manage (new Gtk::HSeparator()));
avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_COLORBOOST_AVOIDCOLORCLIP")));
pack_start (*avoidclip);
pack_start (*Gtk::manage (new Gtk::HSeparator()));
enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_COLORBOOST_ENABLESATLIMITER")));
pack_start (*enablelimiter);
saturationlimiter = new Adjuster (M("TP_COLORBOOST_SATLIMIT"), 0, 200, 0.1, 100);
saturationlimiter->show ();
saturationlimiter->reference ();
colorboost->setAdjusterListener (this);
saturationlimiter->setAdjusterListener (this);
acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &ColorBoost::avoidclip_toggled) );
elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &ColorBoost::enablelimiter_toggled) );
show_all_children ();
}
ColorBoost::~ColorBoost () {
delete saturationlimiter;
}
void ColorBoost::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
colorboost->setEditedState (pedited->colorBoost.amount ? Edited : UnEdited);
saturationlimiter->setEditedState (pedited->colorBoost.saturationlimit ? Edited : UnEdited);
avoidclip->set_inconsistent (!pedited->colorBoost.avoidclip);
enablelimiter->set_inconsistent (!pedited->colorBoost.enable_saturationlimiter);
}
colorboost->setValue (pp->colorBoost.amount);
saturationlimiter->setValue (pp->colorBoost.saturationlimit);
acconn.block (true);
avoidclip->set_active (pp->colorBoost.avoidclip);
acconn.block (false);
elconn.block (true);
enablelimiter->set_active (pp->colorBoost.enable_saturationlimiter);
elconn.block (false);
removeIfThere (this, saturationlimiter, false);
if (enablelimiter->get_active () || enablelimiter->get_inconsistent())
pack_start (*saturationlimiter);
lastACVal = pp->colorBoost.avoidclip;
lastELVal = pp->colorBoost.enable_saturationlimiter;
enableListener ();
}
void ColorBoost::write (ProcParams* pp, ParamsEdited* pedited) {
pp->colorBoost.amount = (int)colorboost->getValue();
pp->colorBoost.avoidclip = avoidclip->get_active ();
pp->colorBoost.enable_saturationlimiter = enablelimiter->get_active ();
pp->colorBoost.saturationlimit = saturationlimiter->getValue ();
if (pedited) {
pedited->colorBoost.amount = colorboost->getEditedState ();
pedited->colorBoost.avoidclip = !avoidclip->get_inconsistent();
pedited->colorBoost.enable_saturationlimiter = !enablelimiter->get_inconsistent();
pedited->colorBoost.saturationlimit = saturationlimiter->getEditedState ();
}
}
void ColorBoost::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
colorboost->setDefault (defParams->colorBoost.amount);
saturationlimiter->setDefault (defParams->colorBoost.saturationlimit);
if (pedited) {
colorboost->setDefaultEditedState (pedited->colorBoost.amount ? Edited : UnEdited);
saturationlimiter->setDefaultEditedState (pedited->colorBoost.saturationlimit ? Edited : UnEdited);
}
else {
colorboost->setDefaultEditedState (Irrelevant);
saturationlimiter->setDefaultEditedState (Irrelevant);
}
}
void ColorBoost::avoidclip_toggled () {
if (batchMode) {
if (avoidclip->get_inconsistent()) {
avoidclip->set_inconsistent (false);
acconn.block (true);
avoidclip->set_active (false);
acconn.block (false);
}
else if (lastACVal)
avoidclip->set_inconsistent (true);
lastACVal = avoidclip->get_active ();
}
if (listener) {
if (avoidclip->get_active ())
listener->panelChanged (EvCBAvoidClip, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvCBAvoidClip, M("GENERAL_DISABLED"));
}
}
void ColorBoost::enablelimiter_toggled () {
if (batchMode) {
if (enablelimiter->get_inconsistent()) {
enablelimiter->set_inconsistent (false);
elconn.block (true);
enablelimiter->set_active (false);
elconn.block (false);
}
else if (lastELVal)
enablelimiter->set_inconsistent (true);
lastELVal = enablelimiter->get_active ();
}
removeIfThere (this, saturationlimiter, false);
if (enablelimiter->get_active () || enablelimiter->get_inconsistent())
pack_start (*saturationlimiter);
if (listener) {
if (enablelimiter->get_active ())
listener->panelChanged (EvCBSatLimiter, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvCBSatLimiter, M("GENERAL_DISABLED"));
}
}
void ColorBoost::adjusterChanged (Adjuster* a, double newval) {
if (listener) {
if (a!=saturationlimiter)
listener->panelChanged (EvCBBoost, Glib::ustring::format ((int)a->getValue()));
else
listener->panelChanged (EvCBSatLimit, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()));
}
}
void ColorBoost::setAdjusterBehavior (bool bcbadd) {
if (!cbAdd && bcbadd || cbAdd && !bcbadd)
colorboost->setLimits (-100, 100, 1, 0);
cbAdd = bcbadd;
}
void ColorBoost::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
colorboost->showEditedCB ();
saturationlimiter->showEditedCB ();
}

53
rtgui/colorboost.h Executable file
View File

@@ -0,0 +1,53 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _COLORBOOST_H_
#define _COLORBOOST_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class ColorBoost : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster* colorboost;
Gtk::CheckButton* avoidclip;
Gtk::CheckButton* enablelimiter;
Adjuster* saturationlimiter;
bool cbAdd;
sigc::connection acconn, elconn;
bool lastACVal, lastELVal;
public:
ColorBoost ();
virtual ~ColorBoost ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void avoidclip_toggled ();
void enablelimiter_toggled ();
void setAdjusterBehavior (bool bcbadd);
};
#endif

120
rtgui/colordenoise.cc Executable file
View File

@@ -0,0 +1,120 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <colordenoise.h>
#include <math.h>
#include <iomanip>
#include <guiutils.h>
using namespace rtengine;
using namespace rtengine::procparams;
ColorDenoise::ColorDenoise () : ToolPanel() {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
amount = Gtk::manage (new Adjuster ("Amount", 1, 100, 1, 30));
pack_start (*enabled);
pack_start (*Gtk::manage (new Gtk::HSeparator()));
pack_start (*amount);
enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ColorDenoise::enabledChanged) );
amount->setAdjusterListener (this);
show_all_children ();
}
void ColorDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
amount->setEditedState (pedited->colorDenoise.amount ? Edited : UnEdited);
enabled->set_inconsistent (!pedited->colorDenoise.enabled);
}
enaConn.block (true);
enabled->set_active (pp->colorDenoise.enabled);
enaConn.block (false);
lastEnabled = pp->colorDenoise.enabled;
amount->setValue (pp->colorDenoise.amount);
enableListener ();
}
void ColorDenoise::write (ProcParams* pp, ParamsEdited* pedited) {
pp->colorDenoise.amount = amount->getValue ();
pp->colorDenoise.enabled = enabled->get_active();
if (pedited) {
pedited->colorDenoise.amount = amount->getEditedState ();
pedited->colorDenoise.enabled = !enabled->get_inconsistent();
}
}
void ColorDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
amount->setDefault (defParams->colorDenoise.amount);
if (pedited)
amount->setDefaultEditedState (pedited->colorDenoise.amount ? Edited : UnEdited);
else
amount->setDefaultEditedState (Irrelevant);
}
void ColorDenoise::adjusterChanged (Adjuster* a, double newval) {
if (listener && enabled->get_active()) {
listener->panelChanged (EvCDNRadius, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()));
}
}
void ColorDenoise::enabledChanged () {
if (batchMode) {
if (enabled->get_inconsistent()) {
enabled->set_inconsistent (false);
enaConn.block (true);
enabled->set_active (false);
enaConn.block (false);
}
else if (lastEnabled)
enabled->set_inconsistent (true);
lastEnabled = enabled->get_active ();
}
if (listener) {
if (enabled->get_active ())
listener->panelChanged (EvCDNEnabled, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvCDNEnabled, M("GENERAL_DISABLED"));
}
}
void ColorDenoise::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
amount->showEditedCB ();
}

47
rtgui/colordenoise.h Executable file
View File

@@ -0,0 +1,47 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _COLORDENOISE_H_
#define _COLORDENOISE_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class ColorDenoise : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster* amount;
Gtk::CheckButton* enabled;
bool lastEnabled;
sigc::connection enaConn;
public:
ColorDenoise ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
};
#endif

108
rtgui/colorshift.cc Executable file
View File

@@ -0,0 +1,108 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <colorshift.h>
#include <iomanip>
using namespace rtengine;
using namespace rtengine::procparams;
ColorShift::ColorShift () : ToolPanel(), aAdd(false), bAdd(false) {
ashift = Gtk::manage (new Adjuster (M("TP_COLORSHIFT_GREENMAGENTA"), -25, 25, 0.1, 0));
pack_start (*ashift);
bshift = Gtk::manage (new Adjuster (M("TP_COLORSHIFT_BLUEYELLOW"), -25, 25, 0.1, 0));
pack_start (*bshift);
ashift->setAdjusterListener (this);
bshift->setAdjusterListener (this);
show_all ();
}
void ColorShift::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
ashift->setEditedState (pedited->colorShift.a ? Edited : UnEdited);
bshift->setEditedState (pedited->colorShift.b ? Edited : UnEdited);
}
ashift->setValue (pp->colorShift.a);
bshift->setValue (pp->colorShift.b);
enableListener ();
}
void ColorShift::write (ProcParams* pp, ParamsEdited* pedited) {
pp->colorShift.a = ashift->getValue ();
pp->colorShift.b = bshift->getValue ();
if (pedited) {
pedited->colorShift.a = ashift->getEditedState ();
pedited->colorShift.b = bshift->getEditedState ();
}
}
void ColorShift::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
ashift->setDefault (defParams->colorShift.a);
bshift->setDefault (defParams->colorShift.b);
if (pedited) {
ashift->setDefaultEditedState (pedited->colorShift.a ? Edited : UnEdited);
bshift->setDefaultEditedState (pedited->colorShift.b ? Edited : UnEdited);
}
else {
ashift->setDefaultEditedState (Irrelevant);
bshift->setDefaultEditedState (Irrelevant);
}
}
void ColorShift::adjusterChanged (Adjuster* a, double newval) {
if (!listener)
return;
if (a==ashift)
listener->panelChanged (EvCShiftA, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()));
else if (a==bshift)
listener->panelChanged (EvCShiftB, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()));
}
void ColorShift::setAdjusterBehavior (bool baadd, bool bbadd) {
if (!aAdd && baadd || aAdd && !baadd)
ashift->setLimits (-25, 25, 0.1, 0);
if (!bAdd && bbadd || bAdd && !bbadd)
bshift->setLimits (-25, 25, 0.1, 0);
aAdd = baadd;
bAdd = bbadd;
}
void ColorShift::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
ashift->showEditedCB ();
bshift->showEditedCB ();
}

46
rtgui/colorshift.h Executable file
View File

@@ -0,0 +1,46 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _COLORSHIFT_H_
#define _COLORSHIFT_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class ColorShift : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster* ashift;
Adjuster* bshift;
bool aAdd, bAdd;
public:
ColorShift ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void setAdjusterBehavior (bool baadd, bool bbadd);
};
#endif

200
rtgui/createicon.cc Executable file
View File

@@ -0,0 +1,200 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <png.h>
void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
png_size_t check;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
check = (png_size_t)fread(data, (png_size_t)1, length, (FILE *)png_ptr->io_ptr);
if (check != length)
{
png_error(png_ptr, "Read Error");
}
}
void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
png_uint_32 check;
check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
if (check != length)
{
png_error(png_ptr, "Write Error");
}
}
void png_flush(png_structp png_ptr) {
FILE *io_ptr;
io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
if (io_ptr != NULL)
fflush(io_ptr);
}
unsigned char* loadPNG (char* fname, int& w, int& h) {
FILE *file = fopen (fname,"rb");
unsigned char header[8];
fread (header, 1, 8, file);
png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info = png_create_info_struct (png);
png_infop end_info = png_create_info_struct (png);
if (setjmp (png_jmpbuf(png))) {
png_destroy_read_struct (&png, &info, &end_info);
fclose (file);
return NULL;
}
//set up png read
png_set_read_fn (png, file, png_read_data);
png_set_sig_bytes (png,8);
png_read_info(png,info);
unsigned long width,height;
int bit_depth,color_type,interlace_type,compression_type,filter_method;
png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type,
&compression_type, &filter_method);
//converting to 32bpp format
if (color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
if (png_get_valid(png,info,PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
if (interlace_type!=PNG_INTERLACE_NONE) {
png_destroy_read_struct (&png, &info, &end_info);
fclose (file);
return NULL;
}
if (color_type & PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(png);
//setting gamma
double gamma;
if (png_get_gAMA(png,info,&gamma))
png_set_gamma(png, 2.0, gamma);
else
png_set_gamma(png,2.0, 0.45455);
int bps = 8;
//updating png info struct
png_read_update_info(png,info);
png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type,
&compression_type, &filter_method);
if (color_type & PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(png);
png_read_update_info(png,info);
png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type,
&compression_type, &filter_method);
unsigned char* data = new unsigned char[width*height*3];
int rowlen = width*3;
unsigned char *row = new unsigned char [rowlen];
for (unsigned int i=0;i<height;i++) {
png_read_row (png, (png_byte*)row, NULL);
memcpy (data+3*i*width, row, 3*width);
}
png_read_end (png, 0);
png_destroy_read_struct (&png, &info, &end_info);
delete [] row;
fclose(file);
w = width;
h = height;
return data;
}
void savePNG (char* fname, unsigned char* data1, unsigned char* data2, int w, int h) {
FILE* file = fopen(fname,"wb");
png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0);
png_infop info = png_create_info_struct(png);
if (setjmp(png_jmpbuf(png))) {
png_destroy_write_struct (&png,&info);
fclose(file);
return;
}
png_set_write_fn (png, file, png_write_data, png_flush);
png_set_compression_level(png,6);
int width = w;
int height = h;
int bps = 8;
png_set_IHDR(png, info, width, height, bps, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_BASE);
int rowlen = width*4;
unsigned char *row = new unsigned char [rowlen];
png_write_info(png,info);
for (unsigned int i=0;i<height;i++) {
for (int j=0; j<width; j++) {
int ofs = 3*(width*i+j);
unsigned char alpha = data2[ofs] - data1[ofs];
if (i==8 && j==8)
printf ("alpha=%d pix=%d\n",(int)alpha, (int)(data1[ofs+0] / (1.0 - alpha/255.0)));
if (alpha<255) {
row[4*j+0] = data1[ofs+0] / (1.0 - alpha/255.0);
row[4*j+1] = data1[ofs+1] / (1.0 - alpha/255.0);
row[4*j+2] = data1[ofs+2] / (1.0 - alpha/255.0);
}
else {
}
row[4*j+3] = 255-alpha;
}
png_write_row (png, (png_byte*)row);
}
png_write_end(png,info);
png_destroy_write_struct(&png,&info);
delete [] row;
fclose (file);
}
int main (int argc, char* argv[]) {
int w, h;
unsigned char* data1 = loadPNG (argv[1], w, h);
unsigned char* data2 = loadPNG (argv[2], w, h);
savePNG (argv[3], data1, data2, w, h);
}

973
rtgui/crop.cc Executable file
View File

@@ -0,0 +1,973 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <crop.h>
#include <options.h>
#include <guiutils.h>
using namespace rtengine;
using namespace rtengine::procparams;
extern Glib::ustring argv0;
extern Options options;
class RefreshSpinHelper {
public:
Crop* crop;
bool notify;
RefreshSpinHelper (Crop* _crop, bool _notify)
: crop(_crop), notify(_notify) {}
};
Crop::Crop () {
clistener = NULL;
maxw = 3000;
maxh = 2000;
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
pack_start(*enabled);
pack_start(*Gtk::manage (new Gtk::HSeparator()));
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_X") +": ")));
x = Gtk::manage (new Gtk::SpinButton ());
x->set_size_request (60, -1);
hb1->pack_start (*x);
hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_Y") + ": ")));
y = Gtk::manage (new Gtk::SpinButton ());
y->set_size_request (60, -1);
hb1->pack_start (*y);
pack_start (*hb1, Gtk::PACK_SHRINK, 2);
Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ());
hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_W") + ": ")));
w = Gtk::manage (new Gtk::SpinButton ());
w->set_size_request (60, -1);
hb2->pack_start (*w);
hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_H") + ": ")));
h = Gtk::manage (new Gtk::SpinButton ());
h->set_size_request (60, -1);
hb2->pack_start (*h);
pack_start (*hb2, Gtk::PACK_SHRINK, 4);
selectCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_SELECTCROP")));
selectCrop->set_image (*Gtk::manage (new Gtk::Image (argv0+"/images/crop16.png")));
pack_start (*selectCrop, Gtk::PACK_SHRINK, 2);
Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ());
fixr = Gtk::manage (new Gtk::CheckButton (M("TP_CROP_FIXRATIO")));
fixr->set_active (1);
hb3->pack_start (*fixr, Gtk::PACK_SHRINK, 4);
ratio = Gtk::manage (new Gtk::ComboBoxText ());
hb3->pack_start (*ratio, Gtk::PACK_SHRINK, 4);
orientation = Gtk::manage (new Gtk::ComboBoxText ());
hb3->pack_start (*orientation);
pack_start (*hb3, Gtk::PACK_SHRINK, 4);
Gtk::HBox* hb31 = Gtk::manage (new Gtk::HBox ());
hb31->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_GUIDETYPE"))), Gtk::PACK_SHRINK, 4);
guide = Gtk::manage (new Gtk::ComboBoxText ());
hb31->pack_start (*guide);
pack_start (*hb31, Gtk::PACK_SHRINK, 4);
dpibox = Gtk::manage (new Gtk::VBox());
dpibox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2);
Gtk::HBox* hb4 = Gtk::manage (new Gtk::HBox ());
hb4->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_DPI"))));
dpi = Gtk::manage (new Gtk::SpinButton ());
dpi->set_size_request (60, -1);
hb4->pack_start (*dpi);
dpibox->pack_start (*hb4, Gtk::PACK_SHRINK, 2);
sizecm = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " cm x " + M("GENERAL_NA") + " cm"));
sizein = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " in x " + M("GENERAL_NA") + " in"));
dpibox->pack_start (*sizecm, Gtk::PACK_SHRINK, 1);
dpibox->pack_start (*sizein, Gtk::PACK_SHRINK, 1);
pack_start (*dpibox, Gtk::PACK_SHRINK, 0);
dpi->set_value (300);
ratio->append_text ("3:2");
ratio->append_text ("4:3");
ratio->append_text ("16:9");
ratio->append_text ("16:10");
ratio->append_text ("5:4");
ratio->append_text ("2:1");
ratio->append_text ("1:1");
ratio->append_text ("DIN");
ratio->set_active (0);
orientation->append_text (M("GENERAL_LANDSCAPE"));
orientation->append_text (M("GENERAL_PORTRAIT"));
orientation->set_active (0);
guide->append_text (M("TP_CROP_GTNONE"));
guide->append_text (M("TP_CROP_GTRULETHIRDS"));
guide->append_text (M("TP_CROP_GTDIAGONALS"));
guide->append_text (M("TP_CROP_GTHARMMEANS1"));
guide->append_text (M("TP_CROP_GTHARMMEANS2"));
guide->append_text (M("TP_CROP_GTHARMMEANS3"));
guide->append_text (M("TP_CROP_GTHARMMEANS4"));
guide->set_active (0);
w->set_range (0, maxw);
h->set_range (0, maxh);
x->set_range (0, maxw);
y->set_range (0, maxh);
x->set_digits (0);
x->set_increments (1,100);
x->set_value (0);
y->set_digits (0);
y->set_increments (1,100);
y->set_value (0);
w->set_digits (0);
w->set_increments (1,100);
w->set_value (200);
h->set_digits (0);
h->set_increments (1,100);
h->set_value (200);
dpi->set_digits (0);
dpi->set_increments (1,100);
dpi->set_range (50, 12000);
dpi->set_value (300);
xconn = x->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true);
yconn = y->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true);
wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::widthChanged), true);
hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::heightChanged), true);
econn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Crop::enabledChanged) );
fconn = fixr->signal_toggled().connect( sigc::mem_fun(*this, &Crop::ratioChanged) );
rconn = ratio->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) );
oconn = orientation->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) );
gconn = guide->signal_changed().connect( sigc::mem_fun(*this, &Crop::notifyListener) );
selectCrop->signal_pressed().connect( sigc::mem_fun(*this, &Crop::selectPressed) );
dpi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) );
nx = ny = nw = nh = 0;
nsx = nsy = nsw = nsh = 0;
lastScale = 1.0;
lastRotationDeg = 0;
show_all ();
}
void Crop::writeOptions () {
options.cropDPI = (int)dpi->get_value ();
}
void Crop::readOptions () {
disableListener ();
dpi->set_value (options.cropDPI);
enableListener ();
}
void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
xconn.block (true);
yconn.block (true);
wconn.block (true);
hconn.block (true);
rconn.block (true);
fconn.block (true);
oconn.block (true);
gconn.block (true);
enabled->set_active (pp->crop.enabled);
// check if the new values are larger than the maximum
double tmp, maxw, maxh;
w->get_range (tmp, maxw);
h->get_range (tmp, maxh);
if (pp->crop.x + pp->crop.w > maxw || pp->crop.y + pp->crop.h > maxh)
setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h);
ratio->set_active_text (pp->crop.ratio);
fixr->set_active (pp->crop.fixratio);
if (pp->crop.orientation == "Landscape")
orientation->set_active (0);
else if (pp->crop.orientation == "Portrait")
orientation->set_active (1);
if (pp->crop.guide == "None")
guide->set_active (0);
else if (pp->crop.guide == "Rule of thirds")
guide->set_active (1);
else if (pp->crop.guide == "Rule of diagonals")
guide->set_active (2);
else if (pp->crop.guide == "Harmonic means 1")
guide->set_active (3);
else if (pp->crop.guide == "Harmonic means 2")
guide->set_active (4);
else if (pp->crop.guide == "Harmonic means 3")
guide->set_active (5);
else if (pp->crop.guide == "Harmonic means 4")
guide->set_active (6);
x->set_value (pp->crop.x);
y->set_value (pp->crop.y);
w->set_value (pp->crop.w);
h->set_value (pp->crop.h);
nx = pp->crop.x;
ny = pp->crop.y;
nw = pp->crop.w;
nh = pp->crop.h;
if (pp->resize.enabled)
lastScale = pp->resize.scale;
else
lastScale = 1.0;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
lastRotationDeg = pp->coarse.rotate;
wDirty = false;
hDirty = false;
xDirty = false;
yDirty = false;
if (pedited) {
wDirty = pedited->crop.w;
hDirty = pedited->crop.h;
xDirty = pedited->crop.x;
yDirty = pedited->crop.y;
if (!pedited->crop.ratio)
ratio->set_active (8);
if (!pedited->crop.orientation)
orientation->set_active (2);
if (!pedited->crop.guide)
guide->set_active (7);
enabled->set_inconsistent (!pedited->crop.enabled);
fixr->set_inconsistent (!pedited->crop.fixratio);
}
lastEnabled = pp->crop.enabled;
lastAspect = pp->crop.fixratio;
xconn.block (false);
yconn.block (false);
wconn.block (false);
hconn.block (false);
rconn.block (false);
fconn.block (false);
oconn.block (false);
gconn.block (false);
enableListener ();
}
void Crop::write (ProcParams* pp, ParamsEdited* pedited) {
pp->crop.enabled = enabled->get_active ();
pp->crop.x = nx;
pp->crop.y = ny;
pp->crop.w = nw;
pp->crop.h = nh;
pp->crop.fixratio = fixr->get_active ();
pp->crop.ratio = ratio->get_active_text ();
if (orientation->get_active_row_number()==0)
pp->crop.orientation = "Landscape";
else if (orientation->get_active_row_number()==1)
pp->crop.orientation = "Portrait";
if (guide->get_active_row_number()==0)
pp->crop.guide = "None";
else if (guide->get_active_row_number()==1)
pp->crop.guide = "Rule of thirds";
else if (guide->get_active_row_number()==2)
pp->crop.guide = "Rule of diagonals";
else if (guide->get_active_row_number()==3)
pp->crop.guide = "Harmonic means 1";
else if (guide->get_active_row_number()==4)
pp->crop.guide = "Harmonic means 2";
else if (guide->get_active_row_number()==5)
pp->crop.guide = "Harmonic means 3";
else if (guide->get_active_row_number()==6)
pp->crop.guide = "Harmonic means 4";
if (pedited) {
pedited->crop.enabled = !enabled->get_inconsistent();
pedited->crop.ratio = ratio->get_active_row_number() != 8;
pedited->crop.orientation = orientation->get_active_row_number() != 2;
pedited->crop.guide = guide->get_active_row_number() != 7;
pedited->crop.fixratio = !fixr->get_inconsistent();
pedited->crop.w = wDirty;
pedited->crop.h = hDirty;
pedited->crop.x = xDirty;
pedited->crop.y = yDirty;
}
}
void Crop::selectPressed () {
if (clistener)
clistener->cropSelectRequested ();
}
void Crop::notifyListener () {
if (listener && enabled->get_active ())
listener->panelChanged (EvCrop, Glib::ustring::compose ("%1=%2, %3=%4\n%5=%6, %7=%8", M("TP_CROP_X"), nx, M("TP_CROP_Y"), ny, M("TP_CROP_W"), nw, M("TP_CROP_H"), nh));
}
void Crop::enabledChanged () {
if (batchMode) {
if (enabled->get_inconsistent()) {
enabled->set_inconsistent (false);
econn.block (true);
enabled->set_active (false);
econn.block (false);
}
else if (lastEnabled)
enabled->set_inconsistent (true);
lastEnabled = enabled->get_active ();
}
if (listener) {
if (enabled->get_active ())
listener->panelChanged (EvCrop, Glib::ustring::compose ("%1=%2, %3=%4\n%5=%6, %7=%8", M("TP_CROP_X"), nx, M("TP_CROP_Y"), ny, M("TP_CROP_W"), nw, M("TP_CROP_H"), nh));
else
listener->panelChanged (EvCrop, M("GENERAL_DISABLED"));
}
}
int notifylistener (void* data) {
gdk_threads_enter ();
((Crop*)data)->notifyListener ();
gdk_threads_leave ();
return 0;
}
int refreshspins (void* data) {
gdk_threads_enter ();
RefreshSpinHelper* rsh = (RefreshSpinHelper*) data;
rsh->crop->refreshSpins (rsh->notify);
delete rsh;
gdk_threads_leave ();
return 0;
}
void Crop::resizeScaleChanged (double rsc) {
lastScale = rsc;
nx = (int)round (nsx * rsc);
ny = (int)round (nsy * rsc);
nw = (int)round (nsw * rsc);
nh = (int)round (nsh * rsc);
if (nx+nw > maxw || ny+nh > maxh)
setDimensions (nx+nw, ny+nh);
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
}
void Crop::hFlipCrop () {
nx = maxw - nx - nw;
nsx = nx / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
}
void Crop::vFlipCrop () {
ny = maxh - ny - nh;
nsy = ny / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
}
void Crop::rotateCrop (int deg) {
int tmp;
switch ((360+deg-lastRotationDeg)%360) {
case 90:
tmp = nx;
nx = maxh - ny - nh;
ny = tmp;
tmp = nw;
nw = nh;
nh = tmp;
break;
case 270:
tmp = ny;
ny = maxw - nx - nw;
nx = tmp;
tmp = nw;
nw = nh;
nh = tmp;
break;
case 180:
nx = maxw - nx - nw;
ny = maxh - ny - nh;
break;
}
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
lastRotationDeg = deg;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
}
void Crop::positionChanged () {
xDirty = true;
yDirty = true;
int X = (int)x->get_value ();
int Y = (int)y->get_value ();
int W = nw;
int H = nh;
cropMoved (X, Y, W, H);
g_idle_add (notifylistener, this);
}
void Crop::widthChanged () {
wDirty = true;
int X = nx;
int Y = ny;
int W = (int)w->get_value ();
int H = nh;
cropWidth2Resized (X, Y, W, H);
g_idle_add (notifylistener, this);
}
void Crop::heightChanged () {
hDirty = true;
int X = nx;
int Y = ny;
int W = nw;
int H = (int)h->get_value ();
cropHeight2Resized (X, Y, W, H);
g_idle_add (notifylistener, this);
}
void Crop::ratioChanged () {
if (batchMode && lastAspect != fixr->get_active ()) {
if (fixr->get_inconsistent()) {
fixr->set_inconsistent (false);
fconn.block (true);
fixr->set_active (false);
fconn.block (false);
}
else if (lastAspect)
fixr->set_inconsistent (true);
lastAspect = fixr->get_active ();
}
if (fixr->get_active() && !fixr->get_inconsistent()) {
// int W = w->get_value ();
// int H = h->get_value ();
int W = nw;
int H = nh;
int X = nx;
int Y = ny;
if (W>=H)
cropWidth2Resized (X, Y, W, H);
else
cropHeight2Resized (X, Y, W, H);
g_idle_add (refreshspins, new RefreshSpinHelper (this, true));
}
}
void Crop::refreshSize () {
if (!batchMode) {
std::ostringstream ostrin;
ostrin.precision (3);
// ostrin << h->get_value()/dpi->get_value() << " in x " << w->get_value()/dpi->get_value() << " in";;
ostrin << nh/dpi->get_value() << " in x " << nw/dpi->get_value() << " in";;
sizein->set_text (ostrin.str ());
std::ostringstream ostrcm;
ostrcm.precision (3);
// ostrcm << h->get_value()/dpi->get_value()*2.54 << " cm x " << w->get_value()/dpi->get_value()*2.54 << " cm";;
ostrcm << nh/dpi->get_value()*2.54 << " cm x " << nw/dpi->get_value()*2.54 << " cm";;
sizecm->set_text (ostrcm.str ());
}
}
void Crop::setDimensions (int mw, int mh) {
maxw = mw;
maxh = mh;
xconn.block (true);
yconn.block (true);
wconn.block (true);
hconn.block (true);
w->set_range (0, maxw);
h->set_range (0, maxh);
x->set_range (0, maxw);
y->set_range (0, maxh);
xconn.block (false);
yconn.block (false);
wconn.block (false);
hconn.block (false);
if (enabled->get_active()==false) {
nx = 0;
ny = 0;
nw = mw;
nh = mh;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
refreshSpins ();
}
refreshSize ();
}
struct setdimparams {
Crop* crop;
int x;
int y;
};
int setdim (void* data) {
gdk_threads_enter ();
setdimparams* params = (setdimparams*)data;
params->crop->setDimensions (params->x, params->y);
delete params;
gdk_threads_leave ();
return 0;
}
void Crop::sizeChanged (int x, int y, int ow, int oh) {
setdimparams* params = new setdimparams;
params->x = x;
params->y = y;
params->crop = this;
g_idle_add (setdim, params);
}
bool Crop::refreshSpins (bool notify) {
xconn.block (true);
yconn.block (true);
wconn.block (true);
hconn.block (true);
x->set_value (nx);
y->set_value (ny);
w->set_value (nw);
h->set_value (nh);
xDirty = true;
yDirty = true;
wDirty = true;
hDirty = true;
xconn.block (false);
yconn.block (false);
wconn.block (false);
hconn.block (false);
refreshSize ();
if (notify)
notifyListener ();
return false;
}
void Crop::cropMoved (int &X, int &Y, int &W, int &H) {
// W = w->get_value ();
// H = h->get_value ();
W = nw;
H = nh;
if (X+W>maxw)
X = maxw-W;
if (Y+H>maxh)
Y = maxh-H;
if (X<0)
X = 0;
if (Y<0)
Y = 0;
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) {
if (W<0)
W = 0;
if (H<0)
H = 0;
if (X<0) {
W += X;
X = 0;
}
if (fixr->get_active()) {
double r = getRatio();
int W2max = (int)round(r*(maxh-Y));
if (W>W2max) {
X += W - W2max;
W = W2max;
}
H = (int)round(W / r);
}
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) {
// X = x->get_value ();
// Y = y->get_value ();
X = nx;
Y = ny;
if (W<0)
W = 0;
if (H<0)
H = 0;
if (W>maxw-X)
W = maxw-X;
if (fixr->get_active()) {
double r = getRatio();
int W2max = (int)round(r*(maxh-Y));
if (W>W2max)
W = W2max;
H = (int)round(W / r);
}
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) {
if (W<0)
W = 0;
if (H<0)
H = 0;
if (Y<0) {
H += Y;
Y = 0;
}
if (fixr->get_active()) {
double r = getRatio();
int H2max = (int)round((maxw-X) / r);
if (H>H2max) {
Y += H - H2max;
H = H2max;
}
W = (int)round(H * r);
}
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) {
// X = x->get_value ();
// Y = y->get_value ();
X = nx;
Y = ny;
if (W<0)
W = 0;
if (H<0)
H = 0;
int H1max = maxh-Y;
if (H>H1max)
H = H1max;
if (fixr->get_active()) {
double r = getRatio ();
int H2max = (int)round ((maxw-X) / r);
if (H>H2max)
H = H2max;
W = (int)round(H * r);
}
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropInit (int &x, int &y, int &w, int &h) {
nx = x;
ny = y;
nw = 1;
nh = 1;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
w = 1; h = 1;
econn.block (true);
enabled->set_active (1);
econn.block (false);
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropResized (int &x, int &y, int& x2, int& y2) {
if (x2<0)
x2 = 0;
if (y2<0)
y2 = 0;
if (x2>=maxw)
x2 = maxw-1;
if (y2>=maxh)
y2 = maxh-1;
int X, Y;
int W;
if (x<x2) {
W = x2 - x + 1;
X = x;
}
else {
W = x - x2 + 1;
X = x2;
}
int H;
if (y<y2) {
H = y2 - y + 1;
Y = y;
}
else {
H = y - y2 + 1;
Y = y2;
}
if (W>maxw)
W = maxw;
if (H>maxh)
H = maxh;
if (fixr->get_active()) {
double r = getRatio ();
if (y<=y2) {
int W2max = (int)round ((maxh-Y) * r);
if (W>W2max)
W = W2max;
}
else {
int W2max = (int)round (y * r);
if (W>W2max)
W = W2max;
}
H = (int)round(W / r);
if (x<x2)
x2 = x + W - 1;
else
x2 = x - W + 1;
if (y<y2)
y2 = y + H - 1;
else
y2 = y - H + 1;
}
if (x<x2) {
W = x2 - x + 1;
X = x;
}
else {
W = x - x2 + 1;
X = x2;
}
if (y<y2) {
H = y2 - y + 1;
Y = y;
}
else {
H = y - y2 + 1;
Y = y2;
}
nx = X;
ny = Y;
nw = W;
nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
void Crop::cropManipReady () {
g_idle_add (notifylistener, this);
}
double Crop::getRatio () {
double r = -1.0;
if (fixr->get_active()==false)
return r;
if (ratio->get_active_row_number()==0)
r = 3.0/2.0;
else if (ratio->get_active_row_number()==1)
r = 4.0/3.0;
else if (ratio->get_active_row_number()==2)
r = 16.0/9.0;
else if (ratio->get_active_row_number()==3)
r = 16.0/10.0;
else if (ratio->get_active_row_number()==4)
r = 5.0/4.0;
else if (ratio->get_active_row_number()==5)
r = 2.0/1.0;
else if (ratio->get_active_row_number()==6)
r = 1.0/1.0;
else if (ratio->get_active_row_number()==7)
r = 1.414;
if (orientation->get_active_row_number()==0)
return r;
else
return 1.0 / r;
}
void Crop::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
ratio->append_text ("(Unchanged)");
orientation->append_text ("(Unchanged)");
guide->append_text ("(Unchanged)");
removeIfThere (this, dpibox);
}

100
rtgui/crop.h Executable file
View File

@@ -0,0 +1,100 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CROP_H_
#define _CROP_H_
#include <gtkmm.h>
#include <cropguilistener.h>
#include <toolpanel.h>
class CropPanelListener {
public:
virtual void cropSelectRequested () {}
};
class Crop : public Gtk::VBox, public CropGUIListener, public ToolPanel, public rtengine::SizeListener {
protected:
Gtk::CheckButton* enabled;
Gtk::CheckButton* fixr;
Gtk::ComboBoxText* ratio;
Gtk::ComboBoxText* orientation;
Gtk::ComboBoxText* guide;
Gtk::Button* selectCrop;
CropPanelListener* clistener;
int opt;
Gtk::SpinButton* x;
Gtk::SpinButton* y;
Gtk::SpinButton* w;
Gtk::SpinButton* h;
Gtk::SpinButton* dpi;
Gtk::Label* sizecm;
Gtk::Label* sizein;
Gtk::VBox* dpibox;
int maxw, maxh;
int nx, ny, nw, nh;
double nsx, nsy, nsw, nsh, lastScale;
int lastRotationDeg;
sigc::connection xconn, yconn, wconn, hconn, econn, fconn, rconn, oconn, gconn;
bool wDirty, hDirty, xDirty, yDirty, lastEnabled, lastAspect;
public:
Crop ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void ratioChanged ();
void refreshSize ();
void selectPressed ();
void setDimensions (int mw, int mh);
void enabledChanged ();
void positionChanged ();
void widthChanged ();
void heightChanged ();
bool refreshSpins (bool notify=false);
void notifyListener ();
void sizeChanged (int w, int h, int ow, int oh);
void readOptions ();
void writeOptions ();
void cropMoved (int &x, int &y, int &w, int &h);
void cropWidth1Resized (int &x, int &y, int &w, int &h);
void cropWidth2Resized (int &x, int &y, int &w, int &h);
void cropHeight1Resized (int &x, int &y, int &w, int &h);
void cropHeight2Resized (int &x, int &y, int &w, int &h);
void cropInit (int &x, int &y, int &w, int &h);
void cropResized (int &x, int &y, int& x2, int& y2);
void cropManipReady ();
double getRatio ();
void setCropPanelListener (CropPanelListener* cl) { clistener = cl; }
void resizeScaleChanged (double rsc);
void hFlipCrop ();
void vFlipCrop ();
void rotateCrop (int deg);
};
#endif

36
rtgui/cropguilistener.h Executable file
View File

@@ -0,0 +1,36 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __CROPGUILISTENER__
#define __CROPGUILISTENER__
class CropGUIListener {
public:
virtual void cropMoved (int &x, int &y, int &w, int &h) {}
virtual void cropWidth1Resized (int &x, int &y, int &w, int &h) {}
virtual void cropWidth2Resized (int &x, int &y, int &w, int &h) {}
virtual void cropHeight1Resized (int &x, int &y, int &w, int &h) {}
virtual void cropHeight2Resized (int &x, int &y, int &w, int &h) {}
virtual void cropInit (int &x, int &y, int &w, int &h) {}
virtual void cropResized (int &x, int &y, int& x2, int& y2) {}
virtual void cropManipReady () {}
virtual double getRatio () {}
};
#endif

328
rtgui/crophandler.cc Executable file
View File

@@ -0,0 +1,328 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <crophandler.h>
using namespace rtengine;
CropHandler::CropHandler ()
: crop(NULL), listener(NULL), cropimg(NULL), ipc(NULL),
cx(0), cy(0), cw(0), ch(0),
cropX(0), cropY(0), cropW(0), cropH(0),
zoom(1000), enabled(false) {
chi = new CropHandlerIdleHelper;
chi->destroyed = false;
chi->pending = 0;
chi->cropHandler = this;
}
CropHandler::~CropHandler () {
if (ipc)
ipc->delSizeListener (this);
setEnabled (false);
if (crop)
crop->destroy ();
cimg.lock ();
if (chi->pending)
chi->destroyed = true;
else
delete chi;
cimg.unlock ();
}
void CropHandler::newImage (StagedImageProcessor* ipc_) {
ipc = ipc_;
cx = 0;
cy = 0;
if (!ipc)
return;
crop = ipc->createCrop ();
ipc->setSizeListener (this);
crop->setListener (enabled ? this : NULL);
initial = true;
}
void CropHandler::sizeChanged (int x, int y, int ow, int oh) { // the ipc notifies it to keep track size changes like rotation
compDim ();
// this should be put into an idle source!!!
/* if (listener)
listener->cropWindowChanged ();
*/
}
double CropHandler::getFitZoom () {
if (ipc) {
double z1 = (double) wh / ipc->getFullHeight ();
double z2 = (double) ww / ipc->getFullWidth ();
return z1<z2 ? z1 : z2;
}
else
return 1.0;
}
void CropHandler::setZoom (int z, int centerx, int centery) {
int x = cx + cw / 2;
int y = cy + ch / 2;
if (centerx>=0)
x = centerx;
if (centery>=0)
y = centery;
zoom = z;
if (zoom>=1000) {
cw = ww * 1000 / zoom;
ch = wh * 1000 / zoom;
}
else {
cw = ww * zoom;
ch = wh * zoom;
}
cx = x - cw / 2;
cy = y - ch / 2;
compDim ();
if (enabled)
update ();
}
void CropHandler::setWSize (int w, int h) {
ww = w;
wh = h;
if (zoom>=1000) {
cw = ww * 1000 / zoom;
ch = wh * 1000 / zoom;
}
else {
cw = ww * zoom;
ch = wh * zoom;
}
compDim ();
if (enabled)
update ();
}
void CropHandler::getWSize (int& w, int &h) {
w = ww;
h = wh;
}
void CropHandler::setPosition (int x, int y, bool update_) {
cx = x;
cy = y;
compDim ();
if (enabled && update_)
update ();
}
void CropHandler::getPosition (int& x, int& y) {
x = cropX;
y = cropY;
}
int createpixbufs (void* data) {
gdk_threads_enter ();
CropHandlerIdleHelper* chi = (CropHandlerIdleHelper*) data;
if (chi->destroyed) {
if (chi->pending == 1)
delete chi;
else
chi->pending--;
gdk_threads_leave ();
return 0;
}
CropHandler* ch = chi->cropHandler;
ch->cimg.lock ();
ch->cropPixbuf.clear ();
if (!ch->enabled) {
delete [] ch->cropimg;
ch->cropimg = NULL;
ch->cimg.unlock ();
gdk_threads_leave ();
return 0;
}
if (ch->cropimg) {
if (ch->cix==ch->cropX && ch->ciy==ch->cropY && ch->ciw==ch->cropW && ch->cih==ch->cropH && ch->cis==(ch->zoom>=1000?1:ch->zoom)) {
// calculate final image size
int czoom = ch->zoom<1000 ? 1000 : ch->zoom;
int imw = ch->cropimg_width * czoom / 1000;
int imh = ch->cropimg_height * czoom / 1000;
if (imw>ch->ww)
imw = ch->ww;
if (imh>ch->wh)
imh = ch->wh;
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, ch->cropimg_height, 3*ch->cropimg_width);
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST);
tmpPixbuf.clear ();
}
delete [] ch->cropimg;
ch->cropimg = NULL;
}
ch->cimg.unlock ();
if (ch->listener) {
ch->listener->cropImageUpdated ();
if (ch->initial) {
ch->listener->initialImageArrived ();
ch->initial = false;
}
}
chi->pending--;
gdk_threads_leave ();
return 0;
}
void CropHandler::setDetailedCrop (IImage8* im, rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip) {
if (!enabled)
return;
cimg.lock ();
cropParams = cp;
cropPixbuf.clear ();
if (cropimg)
delete [] cropimg;
cropimg = NULL;
if (ax==cropX && ay==cropY && aw==cropW && ah==cropH && askip==(zoom>=1000?1:zoom)) {
cropimg_width = im->getWidth ();
cropimg_height = im->getHeight ();
cropimg = new unsigned char [3*cropimg_width*cropimg_height];
memcpy (cropimg, im->getData(), 3*cropimg_width*cropimg_height);
cix = ax;
ciy = ay;
ciw = aw;
cih = ah;
cis = askip;
chi->pending++;
g_idle_add (createpixbufs, chi);
}
cimg.unlock ();
}
bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) {
cwx = cropX;
cwy = cropY;
cww = cropW;
cwh = cropH;
// hack: if called before first size allocation the size will be 0
if (cww<10)
cww = 10;
if (cwh<32)
cwh = 32;
cskip = zoom>=1000 ? 1 : zoom;
return true;
}
void CropHandler::update () {
if (crop) {
// crop->setWindow (cropX, cropY, cropW, cropH, zoom>=1000 ? 1 : zoom); --> we use the "getWindow" hook instead of setting the size before
crop->setListener (this);
cropPixbuf.clear ();
Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), 0, false, true, Glib::THREAD_PRIORITY_NORMAL);
}
}
void CropHandler::setEnabled (bool e) {
enabled = e;
if (!enabled) {
if (crop)
crop->setListener (NULL);
cimg.lock ();
delete [] cropimg;
cropimg = NULL;
cropPixbuf.clear ();
cimg.unlock ();
}
else
update ();
}
bool CropHandler::getEnabled () {
return enabled;
}
void CropHandler::getSize (int& w, int& h) {
w = cropW;
h = cropH;
}
void CropHandler::compDim () {
cropX = cx;
cropY = cy;
cropW = cw;
cropH = ch;
cutRectToImgBounds (cropX, cropY, cropW, cropH);
}
void CropHandler::cutRectToImgBounds (int& x, int& y, int& w, int& h) {
if (ipc) {
if (w > ipc->getFullWidth())
w = ipc->getFullWidth();
if (h > ipc->getFullHeight())
h = ipc->getFullHeight();
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (x + w >= ipc->getFullWidth())
x = ipc->getFullWidth() - w;
if (y + h >= ipc->getFullHeight())
y = ipc->getFullHeight() - h;
}
}

94
rtgui/crophandler.h Executable file
View File

@@ -0,0 +1,94 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __CROPHANDLER__
#define __CROPHANDLER__
#include <rtengine.h>
#include <gtkmm.h>
class CropHandlerListener {
public:
virtual void cropImageUpdated () {}
virtual void cropWindowChanged () {}
virtual void initialImageArrived () {}
};
class CropHandler;
struct CropHandlerIdleHelper {
CropHandler* cropHandler;
bool destroyed;
int pending;
};
class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener {
friend int createpixbufs (void* data);
protected:
int zoom;
int ww, wh; // size of the crop view on the screen
int cx, cy, cw, ch; // position and size of the requested crop
int cropX, cropY, cropW, cropH; // position and size of the crop corresponding to cropPixbuf
bool enabled;
unsigned char* cropimg;
int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis;
bool initial;
rtengine::StagedImageProcessor* ipc;
rtengine::DetailedCrop* crop;
CropHandlerListener* listener;
CropHandlerIdleHelper* chi;
void update ();
void compDim ();
public:
rtengine::procparams::CropParams cropParams;
Glib::RefPtr<Gdk::Pixbuf> cropPixbuf;
Glib::Mutex cimg;
CropHandler ();
~CropHandler ();
void setCropHandlerListener (CropHandlerListener* l) { listener = l; }
void newImage (rtengine::StagedImageProcessor* ipc_);
void setZoom (int z, int centerx=-1, int centery=-1);
double getFitZoom ();
void setWSize (int w, int h);
void getWSize (int& w, int &h);
void setPosition (int x, int y, bool update=true);
void getPosition (int& x, int& y);
void getSize (int& w, int& h);
void setEnabled (bool e);
bool getEnabled ();
// DetailedCropListener interface
void setDetailedCrop (rtengine::IImage8* im, rtengine::procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip);
bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip);
// SizeListener interface
void sizeChanged (int w, int h, int ow, int oh);
void cutRectToImgBounds (int& x, int& y, int& w, int& h);
};
#endif

1030
rtgui/cropwindow.cc Executable file

File diff suppressed because it is too large Load Diff

146
rtgui/cropwindow.h Executable file
View File

@@ -0,0 +1,146 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CROPWINDOW_
#define _CROPWINDOW_
#include <rtengine.h>
#include <gtkmm.h>
#include <lwbutton.h>
#include <lwbuttonset.h>
#include <editenums.h>
#include <crophandler.h>
#include <list>
#include <cropguilistener.h>
#include <pointermotionlistener.h>
class CropWindow;
class CropWindowListener {
public:
virtual void cropPositionChanged (CropWindow*) {}
virtual void cropWindowSizeChanged (CropWindow*) {}
virtual void cropZoomChanged (CropWindow*) {}
virtual void initialImageArrived (CropWindow*) {}
};
class ImageArea;
class CropWindow : public LWButtonListener, public CropHandlerListener {
// state management
ImgEditState state; // current state of user (see enum State)
int action_x, action_y, press_x, press_y;
double rot_deg;
bool onResizeArea;
bool deleted;
bool fitZoomEnabled;
bool fitZoom;
// decoration
Cairo::RefPtr<Cairo::ImageSurface> resizeSurface;
LWButton *bZoomIn, *bZoomOut, *bZoom100, *bZoomFit, *bClose;
LWButtonSet buttonSet;
Glib::ustring cropLabel;
int backColor;
bool decorated;
// sizes, positions
int titleHeight, sideBorderWidth, lowerBorderWidth, upperBorderWidth, sepWidth, minWidth;
int imgAreaX, imgAreaY, imgAreaW, imgAreaH;
int imgX, imgY, imgW, imgH;
int xpos, ypos, width, height;
// image handling
CropHandler cropHandler;
ImageArea* iarea;
int cropZoom; // *1000
// crop gui listener
CropGUIListener* cropgl;
PointerMotionListener* pmlistener;
std::list<CropWindowListener*> listeners;
CropWindow* observedCropWin;
bool onArea (CursorArea a, int x, int y);
void updateCursor (int x, int y);
void drawDecoration (Cairo::RefPtr<Cairo::Context> cr);
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> cr);
void drawSpotWBRectangle (Cairo::RefPtr<Cairo::Context> cr);
void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr);
void translateCoord (int phyx, int phyy, int& imgx, int& imgy);
void changeZoom (int zoom, bool notify=true, int centerx=-1, int centery=-1);
void getObservedFrameArea(int& x, int& y, int& w, int& h);
public:
CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_);
~CropWindow ();
void setDecorated (bool decorated) { this->decorated = decorated; }
void setFitZoomEnabled (bool fze) { fitZoomEnabled = fze; }
void setObservedCropWin (CropWindow* cw) { observedCropWin = cw; }
void setPosition (int x, int y);
void getPosition (int& x, int& y);
void setSize (int w, int h, bool norefresh=false);
void getSize (int& w, int& h);
// zoomlistener interface
void zoomIn ();
void zoomOut ();
void zoom11 ();
void zoomFit ();
double getZoom ();
void setZoom (double zoom);
bool isInside (int x, int y);
void buttonPress (int button, int num, int state, int x, int y);
void buttonRelease (int button, int num, int state, int x, int y);
void pointerMoved (int x, int y);
void expose (Cairo::RefPtr<Cairo::Context> cr);
// interface lwbuttonlistener
void buttonPressed (LWButton* button, int actionCode, void* actionData);
void redrawNeeded (LWButton* button);
// crop handling
void getCropRectangle (int& x, int& y, int& w, int& h);
void getCropPosition (int& x, int& y);
void setCropPosition (int x, int y);
void getCropSize (int& w, int& h);
// listeners
void setCropGUIListener (CropGUIListener* cgl) { cropgl = cgl; }
void setPointerMotionListener (PointerMotionListener* pml) { pmlistener = pml; }
// crop window listeners
void addCropWindowListener (CropWindowListener* l) { listeners.push_back (l); }
void delCropWindowListener (CropWindowListener* l);
// crophandlerlistener interface
void cropImageUpdated ();
void cropWindowChanged ();
void initialImageArrived ();
void remoteMove (int deltaX, int deltaY);
void remoteMoveReady ();
};
#endif

68
rtgui/cursormanager.cc Executable file
View File

@@ -0,0 +1,68 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <cursormanager.h>
#include <options.h>
CursorManager cursorManager;
void CursorManager::init (Glib::RefPtr<Gdk::Window> mainWin) {
cResizeWidth = new Gdk::Cursor (Gdk::SB_H_DOUBLE_ARROW);
cResizeHeight = new Gdk::Cursor (Gdk::SB_V_DOUBLE_ARROW);
cResizeDiag = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER);
cCropMove = new Gdk::Cursor (Gdk::FLEUR);
cCropMoving = new Gdk::Cursor (Gdk::HAND2);
cCropSelection = new Gdk::Cursor (Gdk::CROSSHAIR);
#ifdef _WIN32
cNormal = new Gdk::Cursor (Gdk::LAST_CURSOR);
#else
cNormal = new Gdk::Cursor (Gdk::ARROW);
#endif
cHand = new Gdk::Cursor (cNormal->get_display(), Gdk::Pixbuf::create_from_file(argv0+"/images/openhand22.png"), 10, 10);
cClosedHand = new Gdk::Cursor (cNormal->get_display(), Gdk::Pixbuf::create_from_file(argv0+"/images/closedhand22.png"), 10, 10);
cWB = new Gdk::Cursor (cNormal->get_display(), Gdk::Pixbuf::create_from_file(argv0+"/images/wbpicker16.png"), 1, 12);
mainWindow = mainWin;
}
void CursorManager::setCursor (Glib::RefPtr<Gdk::Window> window, CursorShape shape) {
if (shape==CSArrow)
window->set_cursor (*cNormal);
else if (shape==CSOpenHand)
window->set_cursor (*cHand);
else if (shape==CSClosedHand)
window->set_cursor (*cClosedHand);
else if (shape==CSMove)
window->set_cursor (*cCropMove);
else if (shape==CSResizeWidth)
window->set_cursor (*cResizeWidth);
else if (shape==CSResizeHeight)
window->set_cursor (*cResizeHeight);
else if (shape==CSResizeDiagonal)
window->set_cursor (*cResizeDiag);
else if (shape==CSSpotWB)
window->set_cursor (*cWB);
else if (shape==CSCropSelect)
window->set_cursor (*cCropSelection);
else if (shape==CSStraighten)
window->set_cursor (*cCropSelection);
}

49
rtgui/cursormanager.h Executable file
View File

@@ -0,0 +1,49 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CURSORMANAGER_
#define _CURSORMANAGER_
#include <gtkmm.h>
enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSSpotWB, CSCropSelect, CSStraighten};
class CursorManager {
protected:
Gdk::Cursor* cResizeWidth;
Gdk::Cursor* cResizeHeight;
Gdk::Cursor* cResizeDiag;
Gdk::Cursor* cCropMove;
Gdk::Cursor* cCropMoving;
Gdk::Cursor* cNormal;
Gdk::Cursor* cCropSelection;
Gdk::Cursor* cHand;
Gdk::Cursor* cClosedHand;
Gdk::Cursor* cWB;
Glib::RefPtr<Gdk::Window> mainWindow;
public:
void init (Glib::RefPtr<Gdk::Window> mainWin);
void setCursor (Glib::RefPtr<Gdk::Window> window, CursorShape shape);
};
extern CursorManager cursorManager;
#endif

194
rtgui/curveeditor.cc Executable file
View File

@@ -0,0 +1,194 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <curveeditor.h>
#include <fstream>
#include <string>
#include <multilangmgr.h>
CurveEditor::CurveEditor () {
curve = Gtk::manage (new MyCurve ());
Gtk::AspectFrame* af = Gtk::manage (new Gtk::AspectFrame ("",Gtk::ALIGN_CENTER,Gtk::ALIGN_CENTER,1,false));
af->add (*curve);
curve->set_size_request (-1, 200);
pack_start (*af, Gtk::PACK_EXPAND_WIDGET);
Gtk::HBox* bbox = Gtk::manage (new Gtk::HBox ());
linear = Gtk::manage (new Gtk::Button (M("CURVEEDITOR_LINEAR")));
save = Gtk::manage (new Gtk::Button ());
Gtk::Image* saveImg = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON));
saveImg->show ();
save->add (*saveImg);
load = Gtk::manage (new Gtk::Button ());
Gtk::Image* loadImg = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON));
loadImg->show ();
load->add (*loadImg);
bbox->pack_start (*linear);
bbox->pack_end (*save, Gtk::PACK_SHRINK, 4);
bbox->pack_end (*load, Gtk::PACK_SHRINK, 4);
pack_end (*bbox, Gtk::PACK_SHRINK, 2);
show_all ();
linear->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditor::linearPressed) );
save->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditor::savePressed) );
load->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditor::loadPressed) );
linear->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLINEAR"));
save->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE"));
load->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD"));
}
void CurveEditor::linearPressed () {
std::vector<double> lcurve (5);
lcurve[0] = 1.0;
lcurve[1] = 0.0;
lcurve[2] = 0.0;
lcurve[3] = 1.0;
lcurve[4] = 1.0;
curve->setPoints (lcurve);
curve->queue_draw ();
curve->notifyListener ();
}
void CurveEditor::savePressed () {
Gtk::FileChooserDialog dialog(M("CURVEEDITOR_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE);
// if (options.multiUser)
// dialog.set_current_folder (Options::rtdir + "/" + options.profilePath);
// else
// dialog.set_current_folder (argv0 + "/" + options.profilePath);
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK);
Gtk::FileFilter filter_pp;
filter_pp.set_name(M("CURVEEDITOR_FILEDLGFILTERCURVE"));
filter_pp.add_pattern("*.rtc");
dialog.add_filter(filter_pp);
Gtk::FileFilter filter_any;
filter_any.set_name(M("CURVEEDITOR_FILEDLGFILTERANY"));
filter_any.add_pattern("*");
dialog.add_filter(filter_any);
dialog.set_do_overwrite_confirmation (true);
int result = dialog.run();
if (result==Gtk::RESPONSE_OK) {
std::string fname = dialog.get_filename();
bool hasext = true;
int dotpos = fname.find_last_of ('.');
if (dotpos==Glib::ustring::npos)
hasext = false;
int dirpos1 = fname.find_last_of ('/');
if (dirpos1!=Glib::ustring::npos || dirpos1>dotpos)
hasext = false;
int dirpos2 = fname.find_last_of ('\\');
if (dirpos2!=Glib::ustring::npos || dirpos2>dotpos)
hasext = false;
if (!hasext)
fname = fname + ".rtc";
if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
Glib::ustring msg_ = Glib::ustring("<b>") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "</b>";
Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
int response = msgd.run ();
if (response==Gtk::RESPONSE_NO)
return;
}
std::ofstream f (fname.c_str());
std::vector<double> p = curve->getPoints ();
int ix = 0;
if (p[ix++]<0)
f << "Linear\n";
else
f << "Spline\n";
for (int i=0; i<p.size()/2; i++, ix+=2)
f << p[ix] << ' ' << p[ix+1] << std::endl;
f.close ();
}
}
void CurveEditor::loadPressed () {
Gtk::FileChooserDialog dialog(M("CURVEEDITOR_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN);
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK);
Gtk::FileFilter filter_pp;
filter_pp.set_name(M("CURVEEDITOR_FILEDLGFILTERCURVE"));
filter_pp.add_pattern("*.rtc");
dialog.add_filter(filter_pp);
Gtk::FileFilter filter_any;
filter_any.set_name(M("CURVEEDITOR_FILEDLGFILTERANY"));
filter_any.add_pattern("*");
dialog.add_filter(filter_any);
int result = dialog.run();
if (result==Gtk::RESPONSE_OK) {
std::ifstream f (dialog.get_filename().c_str());
if (f) {
std::vector<double> p;
std::string s;
f >> s;
if (s=="Linear")
p.push_back (-1);
else if (s=="Spline")
p.push_back (1);
else return;
double x;
while (f) {
f >> x;
if (f)
p.push_back (x);
}
curve->setPoints (p);
curve->queue_draw ();
curve->notifyListener ();
}
}
}
void CurveEditor::setCurve (const std::vector<double>& c) {
if (c.size()>4) {
curve->setPoints (c);
curve->queue_draw ();
}
else
linearPressed ();
}
std::vector<double> CurveEditor::getCurve () {
return curve->getPoints ();
}

43
rtgui/curveeditor.h Executable file
View File

@@ -0,0 +1,43 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _CURVEEDITOR_
#define _CURVEEDITOR_
#include <gtkmm.h>
#include <mycurve.h>
class CurveEditor : public Gtk::VBox {
MyCurve* curve;
Gtk::Button* linear;
Gtk::Button* save;
Gtk::Button* load;
public:
CurveEditor ();
void setCurveListener (CurveListener* cl) { curve->setCurveListener (cl); }
void linearPressed ();
void savePressed ();
void loadPressed ();
void setCurve (const std::vector<double>& c);
std::vector<double> getCurve ();
};
#endif

384
rtgui/dirbrowser.cc Executable file
View File

@@ -0,0 +1,384 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <dirbrowser.h>
#ifdef WIN32
#define _WIN32_WINNT 0x0600
#include <windows.h>
#endif
#include <options.h>
#define CHECKTIME 5000
extern Glib::ustring argv0;
DirBrowser::DirBrowser () {
dirtree = new Gtk::TreeView();
scrolledwindow4 = new Gtk::ScrolledWindow();
// dirtree->set_flags(Gtk::CAN_FOCUS);
dirtree->set_headers_visible(false);
dirtree->set_rules_hint(false);
dirtree->set_reorderable(false);
dirtree->set_enable_search(false);
scrolledwindow4->set_flags(Gtk::CAN_FOCUS);
scrolledwindow4->set_border_width(2);
scrolledwindow4->set_shadow_type(Gtk::SHADOW_NONE);
scrolledwindow4->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
scrolledwindow4->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT);
scrolledwindow4->add(*dirtree);
pack_start (*scrolledwindow4);
dirtree->show ();
scrolledwindow4->show ();
}
void DirBrowser::fillDirTree () {
openfolder = Gdk::Pixbuf::create_from_file (argv0+"/images/folder_open.png");
closedfolder = Gdk::Pixbuf::create_from_file (argv0+"/images/folder.png");
icdrom = Gdk::Pixbuf::create_from_file (argv0+"/images/cdrom.png");
ifloppy = Gdk::Pixbuf::create_from_file (argv0+"/images/floppy.png");
ihdd = Gdk::Pixbuf::create_from_file (argv0+"/images/hdd.png");
iremovable = Gdk::Pixbuf::create_from_file (argv0+"/images/usbpendrive.png");
inetwork = Gdk::Pixbuf::create_from_file (argv0+"/images/network.png");
//Create the Tree model:
dirTreeModel = Gtk::TreeStore::create(dtColumns);
dirtree->set_model (dirTreeModel);
fillRoot ();
Gtk::CellRendererPixbuf* render_pb = new Gtk::CellRendererPixbuf ();
tvc.pack_start (*render_pb, false);
tvc.add_attribute(*render_pb, "pixbuf-expander-closed", 1);
tvc.add_attribute(*render_pb, "pixbuf", 1);
tvc.add_attribute(*render_pb, "pixbuf-expander-open", 0);
tvc.pack_start (crt);
tvc.add_attribute(crt, "text", 2);
crt.property_ypad() = 0;
render_pb->property_ypad() = 0;
dirtree->append_column(tvc);
dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded));
dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated));
}
#ifdef WIN32
void DirBrowser::addRoot (char letter) {
char volume[4];
volume[0] = letter;
strcpy (volume+1, ":\\");
Gtk::TreeModel::iterator root = dirTreeModel->append();
root->set_value (dtColumns.filename, Glib::ustring(volume));
root->set_value (dtColumns.dirname, Glib::ustring(volume));
int type = GetDriveType (volume);
if (type==DRIVE_CDROM) {
root->set_value (0, icdrom);
root->set_value (1, icdrom);
}
else if (type==DRIVE_REMOVABLE) {
if (letter-'A'<2) {
root->set_value (0, ifloppy);
root->set_value (1, ifloppy);
}
else {
root->set_value (0, iremovable);
root->set_value (1, iremovable);
}
}
else if (type==DRIVE_REMOTE) {
root->set_value (0, inetwork);
root->set_value (1, inetwork);
}
else if (type==DRIVE_FIXED) {
root->set_value (0, ihdd);
root->set_value (1, ihdd);
}
Gtk::TreeModel::iterator child = dirTreeModel->append (root->children());
child->set_value (dtColumns.filename, Glib::ustring("foo"));
}
void DirBrowser::updateDirTreeRoot () {
for (Gtk::TreeModel::iterator i=dirTreeModel->children().begin(); i!=dirTreeModel->children().end(); i++)
updateDirTree (i);
}
void DirBrowser::updateDirTree (const Gtk::TreeModel::iterator& iter) {
if (dirtree->row_expanded (dirTreeModel->get_path (iter))) {
updateDir (iter);
for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++)
updateDirTree (i);
}
}
void DirBrowser::updateVolumes () {
int nvolumes = GetLogicalDrives ();
if (nvolumes!=volumes) {
for (int i=0; i<32; i++)
if (((volumes >> i) & 1) && !((nvolumes >> i) & 1)) { // volume i has been deleted
for (Gtk::TreeModel::iterator iter = dirTreeModel->children().begin(); iter!=dirTreeModel->children().end(); iter++)
if (iter->get_value (dtColumns.filename).c_str()[0]-'A' == i) {
dirTreeModel->erase (iter);
break;
}
}
else if (!((volumes >> i) & 1) && ((nvolumes >> i) & 1))
addRoot ('A'+i); // volume i has been added
volumes = nvolumes;
}
}
int _updateVolumes (void* br) {
gdk_threads_enter ();
((DirBrowser*)br)->updateVolumes ();
gdk_threads_leave ();
return 1;
}
int _updateDirTree (void* br) {
gdk_threads_enter ();
((DirBrowser*)br)->updateDirTreeRoot ();
gdk_threads_leave ();
return 0;
}
void DirBrowser::winDirChanged () {
g_idle_add (_updateDirTree, this);
}
#endif
void DirBrowser::fillRoot () {
#ifdef WIN32
volumes = GetLogicalDrives ();
for (int i=0; i<32; i++)
if ((volumes >> i) & 1)
addRoot ('A'+i);
// since sigc++ is not thread safe, we have to use the glib function
g_timeout_add (CHECKTIME, _updateVolumes, this);
#else
Gtk::TreeModel::Row rootRow = *(dirTreeModel->append());
rootRow[dtColumns.filename] = "/";
rootRow[dtColumns.dirname] = "/";
Gtk::TreeModel::Row childRow = *(dirTreeModel->append(rootRow.children()));
childRow[dtColumns.filename] = "foo";
#endif
}
void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) {
expandSuccess = false;
int todel = iter->children().size();
try {
std::vector<Glib::ustring> subDirs;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
if (!dir)
return;
Glib::RefPtr<Gio::FileEnumerator> dirList = dir->enumerate_children ();
try {
for (Glib::RefPtr<Gio::FileInfo> info = dirList->next_file(); info; info = dirList->next_file())
if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || options.fbShowHidden))
subDirs.push_back (info->get_name());
}
catch (...) {}
std::sort (subDirs.begin(), subDirs.end());
for (int i=0; i<subDirs.size(); i++)
addDir (iter, subDirs[i]);
for (int i=0; i<todel; i++)
dirTreeModel->erase (iter->children().begin());
expandSuccess = true;
#ifdef _WIN32
Glib::RefPtr<WinDirMonitor> monitor = Glib::RefPtr<WinDirMonitor>(new WinDirMonitor (iter->get_value (dtColumns.dirname), this));
iter->set_value (dtColumns.monitor, monitor);
#else
Glib::RefPtr<Gio::FileMonitor> monitor = dir->monitor_directory ();
iter->set_value (dtColumns.monitor, monitor);
monitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &DirBrowser::file_changed), iter, dir->get_parse_name()));
#endif
}
catch (Glib::Exception &ex) {
printf ("HEJJ!\n");
dirtree->collapse_row (path);
}
}
void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) {
// first test if some files are deleted
bool change = true;
while (change) {
change = false;
for (Gtk::TreeModel::iterator it=iter->children().begin(); it!=iter->children().end(); it++)
if (!Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS)
|| !Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) {
dirTreeModel->erase (it);
change = true;
break;
}
}
// test if new files are created
try {
std::vector<Glib::ustring> subDirs;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
if (!dir)
return;
Glib::RefPtr<Gio::FileEnumerator> dirList = dir->enumerate_children ();
for (Glib::RefPtr<Gio::FileInfo> info = dirList->next_file(); info; info = dirList->next_file())
if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || options.fbShowHidden))
subDirs.push_back (info->get_name());
for (int i=0; i<subDirs.size(); i++) {
bool found = false;
for (Gtk::TreeModel::iterator it=iter->children().begin(); it!=iter->children().end(); it++)
if (it->get_value (dtColumns.filename)==subDirs[i]) {
found = true;
break;
}
if (!found)
addDir (iter, subDirs[i]);
}
}
catch (Glib::Exception &ex) {
printf ("HEJJ!\n");
}
}
void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname) {
Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children());
child->set_value (dtColumns.filename, dirname);
child->set_value (0, openfolder);
child->set_value (1, closedfolder);
Glib::ustring fullname = Glib::build_filename (iter->get_value (dtColumns.dirname), dirname);
child->set_value (dtColumns.dirname, fullname);
Glib::RefPtr<Gio::File> f = Gio::File::create_for_path (fullname);
Gtk::TreeModel::iterator fooRow = dirTreeModel->append(child->children());
fooRow->set_value (dtColumns.filename, Glib::ustring("foo"));
}
void DirBrowser::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) {
Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname);
if (Glib::file_test (dname, Glib::FILE_TEST_IS_DIR))
for (int i=0; i<dllisteners.size(); i++)
dllisteners[i]->dirSelected (dname);
}
Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) {
Gtk::TreeModel::Path path;
path.append_index(0);
int end = 0;
int beg = 0;
char* dir = new char [1024];
char* dcpy = strdup (absDirPath.c_str());
dir = strtok (dcpy, "/\\");
int count = 0;
expandSuccess = true;
#ifndef _WIN32
Gtk::TreeModel::iterator j = dirTreeModel->get_iter (path);
path.up ();
path.append_index (0);
row_expanded(j, path);
path.append_index (0);
#endif
while (dir) {
Glib::ustring dirstr = dir;
#ifdef _WIN32
if (count==0)
dirstr = dirstr + "\\";
#endif
Gtk::TreeModel::iterator i = dirTreeModel->get_iter (path);
int ix = 0;
while (i && expandSuccess) {
Gtk::TreeModel::Row crow = *i;
Glib::ustring str =crow[dtColumns.filename];
#ifdef _WIN32
if (str.casefold()==dirstr.casefold()) {
#else
if (str==dirstr) {
#endif
path.up ();
path.append_index (ix);
row_expanded(i, path);
path.append_index (0);
break;
}
ix++;
i++;
}
count++;
dir = strtok(NULL, "/\\");
}
delete dir;
delete dcpy;
path.up ();
dirtree->expand_to_path (path);
return path;
}
void DirBrowser::open (const Glib::ustring& dirname, const Glib::ustring& fileName) {
dirtree->collapse_all ();
Glib::ustring absDirPath = Gio::File::create_for_path(dirname)->get_parse_name ();
Gtk::TreePath path = expandToDir (absDirPath);
if (expandSuccess) {
dirtree->scroll_to_row (path);
dirtree->get_selection()->select (path);
for (int i=0; i<dllisteners.size(); i++)
dllisteners[i]->dirSelected (absDirPath, Glib::build_filename (absDirPath, fileName));
}
}
void DirBrowser::file_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName) {
if (!file || !Glib::file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type==Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED)
return;
gdk_threads_enter();
updateDir (iter);
gdk_threads_leave();
}
void DirBrowser::selectDir (Glib::ustring dir) {
open (dir, "");
}

103
rtgui/dirbrowser.h Executable file
View File

@@ -0,0 +1,103 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _DIRBROWSER_
#define _DIRBROWSER_
#include <gtkmm.h>
#include <giomm.h>
#ifdef _WIN32
#include <windirmonitor.h>
#endif
#include <dirselectionlistener.h>
#include <dirbrowserremoteinterface.h>
class DirBrowser : public Gtk::VBox, public DirBrowserRemoteInterface
#ifdef _WIN32
, public WinDirChangeListener
#endif
{
private:
Glib::RefPtr<Gtk::TreeStore> dirTreeModel;
struct DirTreeColumns : public Gtk::TreeModelColumnRecord {
public:
Gtk::TreeModelColumn<Glib::ustring> filename;
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon1;
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon2;
Gtk::TreeModelColumn<Glib::ustring> dirname;
#ifdef _WIN32
Gtk::TreeModelColumn<Glib::RefPtr<WinDirMonitor> > monitor;
#else
Gtk::TreeModelColumn<Glib::RefPtr<Gio::FileMonitor> > monitor;
#endif
DirTreeColumns() { add(icon1); add(icon2); add(filename); add(dirname); add(monitor); }
};
Gtk::TreeViewColumn tvc;
Gtk::CellRendererText crt;
Gtk::CellRendererPixbuf crb;
DirTreeColumns dtColumns;
Gtk::TreeView *dirtree;
Gtk::ScrolledWindow *scrolledwindow4;
std::vector<DirSelectionListener*> dllisteners;
void fillRoot ();
Glib::RefPtr<Gdk::Pixbuf> openfolder;
Glib::RefPtr<Gdk::Pixbuf> closedfolder;
Glib::RefPtr<Gdk::Pixbuf> icdrom;
Glib::RefPtr<Gdk::Pixbuf> ifloppy;
Glib::RefPtr<Gdk::Pixbuf> ihdd;
Glib::RefPtr<Gdk::Pixbuf> inetwork;
Glib::RefPtr<Gdk::Pixbuf> iremovable;
bool expandSuccess;
#ifdef WIN32
int volumes;
public:
void updateVolumes ();
void updateDirTree (const Gtk::TreeModel::iterator& iter);
void updateDirTreeRoot ();
void winDirChanged ();
private:
void addRoot (char letter);
#endif
void addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname);
Gtk::TreePath expandToDir (const Glib::ustring& dirName);
void updateDir (const Gtk::TreeModel::iterator& iter);
void notifyListeners ();
public:
DirBrowser ();
void fillDirTree ();
void row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path);
void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
void file_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName);
void open (const Glib::ustring& dirName, const Glib::ustring& fileName=""); // goes to dir "dirName" and selects file "fileName"
void addDirSelectionListener (DirSelectionListener* l) { dllisteners.push_back (l); }
void selectDir (Glib::ustring dir);
};
#endif

View File

@@ -0,0 +1,31 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _DIRBROWSERREMOTEINTERFACE_
#define _DIRBROWSERREMOTEINTERFACE_
#include <glibmm.h>
class DirBrowserRemoteInterface {
public:
virtual void selectDir (Glib::ustring dir) {}
};
#endif

30
rtgui/dirselectionlistener.h Executable file
View File

@@ -0,0 +1,30 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _DIRSELECTIONLISTENER_
#define _DIRSELECTIONLISTENER_
#include <glibmm.h>
class DirSelectionListener {
public:
virtual void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile="") {}
};
#endif

83
rtgui/distortion.cc Executable file
View File

@@ -0,0 +1,83 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <distortion.h>
#include <iomanip>
using namespace rtengine;
using namespace rtengine::procparams;
Distortion::Distortion () {
distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0));
distor->setAdjusterListener (this);
distor->show();
pack_start (*distor);
distAdd = false;
}
void Distortion::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited)
distor->setEditedState (pedited->distortion.amount ? Edited : UnEdited);
distor->setValue (pp->distortion.amount);
enableListener ();
}
void Distortion::write (ProcParams* pp, ParamsEdited* pedited) {
pp->distortion.amount = distor->getValue ();
if (pedited)
pedited->distortion.amount = distor->getEditedState ();
}
void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
distor->setDefault (defParams->distortion.amount);
if (pedited)
distor->setDefaultEditedState (pedited->distortion.amount ? Edited : UnEdited);
else
distor->setDefaultEditedState (Irrelevant);
}
void Distortion::adjusterChanged (Adjuster* a, double newval) {
if (listener)
listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue()));
}
void Distortion::setAdjusterBehavior (bool bvadd) {
if (!distAdd && bvadd || distAdd && !bvadd)
distor->setLimits (-0.5, 0.5, 0.001, 0);
distAdd = bvadd;
}
void Distortion::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
distor->showEditedCB ();
}

45
rtgui/distortion.h Executable file
View File

@@ -0,0 +1,45 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _DISTORTION_H_
#define _DISTORTION_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class Distortion : public Gtk::VBox, public AdjusterListener, public ToolPanel {
protected:
Adjuster* distor;
bool distAdd;
public:
Distortion ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void setAdjusterBehavior (bool bvadd);
};
#endif

25
rtgui/editedstate.h Executable file
View File

@@ -0,0 +1,25 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _EDITEDSTATE_
#define _EDITEDSTATE_
enum EditedState { UnEdited=0, Edited=1, Irrelevant=2 };
#endif

25
rtgui/editenums.h Executable file
View File

@@ -0,0 +1,25 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _EDITENUMS_
#define _EDITENUMS_
enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove};
enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropBottom, CropLeft, CropRight, CropInside, CropResize, CropObserved};
#endif

801
rtgui/editorpanel.cc Executable file
View File

@@ -0,0 +1,801 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <editorpanel.h>
#include <options.h>
#include <progressdialog.h>
#include <rtwindow.h>
#include <guiutils.h>
#include <procparamchangers.h>
using namespace rtengine::procparams;
EditorPanel::EditorPanel (Thumbnail* tmb, rtengine::InitialImage* isrc) : parent(NULL), beforeIarea(NULL), beforePreviewHandler(NULL), beforeIpc(NULL) {
epih = new EditorPanelIdleHelper;
epih->epanel = this;
epih->destroyed = false;
epih->pending = 0;
// construct toolpanelcoordinator
tpc = new ToolPanelCoordinator ();
// build GUI
// build left side panel
leftbox = Gtk::manage (new Gtk::VBox ());
leftbox->set_border_width (4);
histogramPanel = Gtk::manage (new HistogramPanel ());
histogramPanel->set_size_request (-1, 150);
// leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
profilep = Gtk::manage (new ProfilePanel ());
Gtk::Frame* ppframe = Gtk::manage (new Gtk::Frame ());
ppframe->add (*profilep);
ppframe->set_label (M("PROFILEPANEL_LABEL"));
// leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
navigator = Gtk::manage (new Navigator ());
navigator->previewWindow->set_size_request (-1, 150);
leftbox->pack_start (*navigator, Gtk::PACK_SHRINK, 4);
history = Gtk::manage (new History ());
leftbox->pack_start (*history);
leftbox->show_all ();
// build the middle of the screen
Gtk::VBox* editbox = Gtk::manage (new Gtk::VBox ());
info = Gtk::manage (new Gtk::ToggleButton ());
Gtk::Image* infoimg = Gtk::manage (new Gtk::Image (argv0+"/images/info.png"));
info->add (*infoimg);
info->set_relief(Gtk::RELIEF_NONE);
info->set_tooltip_text (M("MAIN_TOOLTIP_QINFO"));
beforeAfter = Gtk::manage (new Gtk::ToggleButton ("B|A"));
beforeAfter->set_tooltip_text ("Toggle before/after view");
Gtk::VSeparator* vsept = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ());
hidehp = Gtk::manage (new Gtk::ToggleButton ());
Gtk::Label* hidehpLabel = Gtk::manage (new Gtk::Label ());
hidehpLabel->set_markup ("<b>H</b>");
Gtk::Image* hpimg = Gtk::manage (new Gtk::Image (argv0+"/images/left.png"));
Gtk::HBox* hidehpBox = Gtk::manage (new Gtk::HBox ());
hidehpBox->pack_start (*hpimg, Gtk::PACK_SHRINK, 2);
hidehpBox->pack_start (*hidehpLabel, Gtk::PACK_SHRINK, 2);
hidehp->add (*hidehpBox);
hidehp->set_relief(Gtk::RELIEF_NONE);
hidehp->set_active (options.showHistory);
hidehp->set_tooltip_text (M("MAIN_TOOLTIP_HIDEHP"));
Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ());
Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ());
iarea = new ImageAreaPanel ();
Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ());
toolBarPanel->pack_start (*hidehp, Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_start (*vseph, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_start (*info, Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_start (*beforeAfter, Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_start (*vsepi, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1);
toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2);
toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 4);
toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 4);
toolBarPanel->pack_end (*iarea->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0);
toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2);
afterBox = Gtk::manage (new Gtk::VBox ());
afterBox->pack_start (*iarea);
beforeAfterBox = Gtk::manage (new Gtk::HBox());
beforeAfterBox->pack_start (*afterBox);
editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK);
editbox->pack_start (*beforeAfterBox);
// build right side panel
vboxright = Gtk::manage (new Gtk::VBox (false, 0));
vboxright->set_border_width (4);
vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4);
vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 4);
// main notebook
vboxright->pack_start (*tpc->toolPanelNotebook);
// buttons & status
Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ());
saveimgas = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_SAVE")));
saveimgas->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)));
queueimg = Gtk::manage (new Gtk::Button ("Put to queue"));
queueimg->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-execute"), Gtk::ICON_SIZE_BUTTON)));
sendtogimp = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_SENDTOEDITOR")));
sendtogimp->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/gimp.png")));
iops->pack_start (*saveimgas, Gtk::PACK_SHRINK);
iops->pack_start (*queueimg, Gtk::PACK_SHRINK);
iops->pack_start (*sendtogimp, Gtk::PACK_SHRINK);
statusBox = Gtk::manage (new Gtk::HBox ());
progressLabel = Gtk::manage (new Gtk::Label(""));
statusBox->pack_start (*progressLabel);
red = new Gtk::Image (argv0+"/images/red.png");
green = new Gtk::Image (argv0+"/images/green.png");
red->show ();
green->show ();
statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
iops->pack_start(*statusBox, Gtk::PACK_SHRINK, 4);
iops->pack_end (*iarea->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1);
iops->pack_end (*vsepz2, Gtk::PACK_SHRINK, 2);
editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4);
editbox->pack_start (*iops, Gtk::PACK_SHRINK, 4);
editbox->show_all ();
// build screen
hpanedl = Gtk::manage (new Gtk::HPaned());
hpanedr = Gtk::manage (new Gtk::HPaned());
leftbox->reference ();
vboxright->reference ();
if (options.showHistory) {
hpanedl->pack1(*leftbox, false, true);
hpanedl->set_position (options.historyPanelWidth);
}
Gtk::Frame* vbfr = Gtk::manage (new Gtk::Frame ());
vbfr->add (*editbox);
hpanedl->pack2(*vbfr, true, true);
hpanedr->pack1(*hpanedl, true, true);
hpanedr->pack2(*vboxright, false, true);
pack_start (*hpanedr);
show_all ();
// save as dialog
if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR))
saveAsDialog = new SaveAsDialog (options.lastSaveAsPath);
else
saveAsDialog = new SaveAsDialog (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES));
// connect listeners
profilep->setProfileChangeListener (tpc);
history->setProfileChangeListener (tpc);
history->setHistoryBeforeLineListener (this);
tpc->addPParamsChangeListener (profilep);
tpc->addPParamsChangeListener (history);
tpc->addPParamsChangeListener (this);
iarea->imageArea->setCropGUIListener (tpc->getCropGUIListener());
iarea->imageArea->setPointerMotionListener (navigator);
iarea->imageArea->setImageAreaToolListener (tpc);
// initialize components
info->set_active (options.showInfo);
tpc->readOptions ();
// connect event handlers
info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) );
beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) );
hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) );
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) );
// open image
open (tmb, isrc);
}
bool EditorPanel::beforeClosing () {
options.toolPanelWidth = vboxright->get_width ();
return true;
}
EditorPanel::~EditorPanel () {
history->setHistoryBeforeLineListener (NULL);
// the order is important!
delete iarea;
delete beforeIarea;
if (ipc)
ipc->setPreviewImageListener (NULL);
if (beforeIpc)
beforeIpc->setPreviewImageListener (NULL);
delete previewHandler;
delete beforePreviewHandler;
if (ipc)
close ();
if (epih->pending)
epih->destroyed = true;
else
delete epih;
delete tpc;
delete red;
delete green;
delete leftbox;
delete vboxright;
delete saveAsDialog;
}
void EditorPanel::on_realize () {
Gtk::VBox::on_realize ();
vboxright->set_size_request (options.toolPanelWidth, -1);
}
rtengine::InitialImage* EditorPanel::loadImage (Thumbnail* tmb) {
// try to load the image
Glib::ustring filename = tmb->getFileName ();
int error;
// InitialImage* isrc = InitialImage::load (filename, tmb->getType()==FT_Raw, error, this);
ProgressDialog<rtengine::InitialImage*>* pdload = new ProgressDialog<rtengine::InitialImage*> (M("PROGRESSDLG_LOADING"));
rtengine::InitialImage* isrc;
pdload->setFunc (sigc::bind(sigc::ptr_fun(&rtengine::InitialImage::load), filename, tmb->getType()==FT_Raw, &error, pdload->getProgressListener()), &isrc);
pdload->start ();
delete pdload;
if (error)
return NULL;
else
return isrc;
}
void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) {
// initialize everything
openThm = tmb;
openThm->increaseRef ();
previewHandler = new PreviewHandler ();
this->isrc = isrc;
ipc = rtengine::StagedImageProcessor::create (isrc);
ipc->setProgressListener (this);
ipc->setPreviewImageListener (previewHandler);
ipc->setPreviewScale (10);
tpc->initImage (ipc, tmb->getType()==FT_Raw);
ipc->setHistogramListener (histogramPanel);
// iarea->fitZoom (); // tell to the editorPanel that the next image has to be fitted to the screen
iarea->imageArea->setPreviewHandler (previewHandler);
iarea->imageArea->setImProcCoordinator (ipc);
navigator->previewWindow->setPreviewHandler (previewHandler);
navigator->previewWindow->setImageArea (iarea->imageArea);
// try to load the last saved parameters from the cache or from the pp2 file
ProcParams* ldprof = NULL;
if (openThm->hasProcParams()) {
ldprof = new ProcParams ();
*ldprof = openThm->getProcParams ();
}
// initialize profile
if (openThm->getType()!=FT_Raw)
profilep->initProfile (options.defProfImg, ldprof, NULL);
else
profilep->initProfile (options.defProfRaw, ldprof, NULL);
openThm->addThumbnailListener (this);
info_toggled ();
}
void EditorPanel::close () {
saveProfile ();
// close image processor and the current thumbnail
tpc->closeImage (); // this call stops image processing
tpc->writeOptions ();
if (ipc)
rtengine::StagedImageProcessor::destroy (ipc);
if (beforeIpc)
rtengine::StagedImageProcessor::destroy (beforeIpc);
openThm->removeThumbnailListener (this);
openThm->decreaseRef ();
}
void EditorPanel::saveProfile () {
ProcParams params;
ipc->getParams (&params);
if (options.saveParamsFile)
params.save (openThm->getFileName() + ".pp2");
if (openThm && options.saveParamsCache)
openThm->setProcParams (params, EDITOR);
}
Glib::ustring EditorPanel::getShortName () {
return Glib::path_get_basename (openThm->getFileName ());
}
Glib::ustring EditorPanel::getFileName () {
return openThm->getFileName ();
}
// TODO!!!
void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) {
// if (ev!=EvPhotoLoaded)
// saveLabel->set_markup (Glib::ustring("<span foreground=\"#AA0000\" weight=\"bold\">") + M("MAIN_BUTTON_SAVE") + "</span>");
}
struct spsparams {
bool state;
EditorPanelIdleHelper* epih;
};
int setprocstate (void* data) {
gdk_threads_enter ();
spsparams* p = (spsparams*)data;
if (p->epih->destroyed) {
if (p->epih->pending == 1)
delete p->epih;
else
p->epih->pending--;
delete p;
gdk_threads_leave ();
return 0;
}
p->epih->epanel->refreshProcessingState (p->state);
p->epih->pending--;
delete p;
gdk_threads_leave ();
return 0;
}
void EditorPanel::setProgressState (int state) {
epih->pending++;
spsparams* p = new spsparams;
p->state = state;
p->epih = epih;
g_idle_add (setprocstate, p);
}
void EditorPanel::refreshProcessingState (bool state) {
// Set proc params of thumbnail. It saves it into the cache and updates the file browser.
if (ipc && openThm && !state && tpc->getChangedState()) {
rtengine::procparams::ProcParams pparams;
ipc->getParams (&pparams);
openThm->setProcParams (pparams, EDITOR, false);
}
// change state of the led
std::vector<Widget*> children = (std::vector<Widget*>) statusBox->get_children();
if (children.size()>=1) {
Gtk::Widget* wlast = children[children.size()-1];
if (wlast)
statusBox->remove (*wlast);
}
if (state)
statusBox->pack_end (*red, Gtk::PACK_SHRINK, 4);
else
statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4);
}
struct errparams {
Glib::ustring descr;
EditorPanelIdleHelper* epih;
};
void EditorPanel::displayError (Glib::ustring descr) {
if (parent) {
Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, descr, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd->set_title (M("MAIN_MSG_CANNOTSAVE"));
msgd->run ();
delete msgd;
}
}
int disperror (void* data) {
gdk_threads_enter ();
errparams* p = (errparams*)data;
if (p->epih->destroyed) {
if (p->epih->pending == 1)
delete p->epih;
else
p->epih->pending--;
delete p;
gdk_threads_leave ();
return 0;
}
p->epih->epanel->displayError (p->descr);
p->epih->pending--;
delete p;
gdk_threads_leave ();
return 0;
}
void EditorPanel::error (Glib::ustring descr) {
epih->pending++;
errparams* p = new errparams;
p->descr = descr;
p->epih = epih;
g_idle_add (disperror, p);
}
void EditorPanel::info_toggled () {
Glib::ustring infoString;
const rtengine::ImageMetaData* idata = ipc->getInitialImage()->getMetaData();
if (idata && idata->hasExif())
infoString = Glib::ustring::compose ("%1 %2\nF/%3 %4 sec\n%5: %6\n%7: %8 mm\n",
Glib::ustring(idata->getMake()), Glib::ustring(idata->getModel()),
Glib::ustring(idata->apertureToString(idata->getFNumber())), Glib::ustring(idata->shutterToString(idata->getShutterSpeed())),
M("QINFO_ISO"), idata->getISOSpeed(),
M("QINFO_FOCALLENGTH"), idata->getFocalLen())
+ Glib::ustring::compose ("%1: %2", M("QINFO_LENS"), Glib::ustring(idata->getLens()));
else
infoString = M("QINFO_NOEXIF");
iarea->imageArea->setInfoText (infoString);
iarea->imageArea->infoEnabled (info->get_active ());
}
void EditorPanel::hideHistoryActivated () {
removeIfThere (hpanedl, leftbox, false);
if (hidehp->get_active())
hpanedl->pack1 (*leftbox, false, true);
}
bool EditorPanel::handleShortcutKey (GdkEventKey* event) {
if (event->keyval==GDK_H || event->keyval==GDK_h) {
hidehp->set_active (!hidehp->get_active());
return true;
}
else if ((event->keyval==GDK_Z || event->keyval==GDK_z) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) {
history->undo ();
return true;
}
else if ((event->keyval==GDK_Z || event->keyval==GDK_z) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) {
history->redo ();
return true;
}
else if (event->keyval==GDK_w || event->keyval==GDK_W) {
tpc->getToolBar()->wb_pressed ();
return true;
}
else if (event->keyval==GDK_c || event->keyval==GDK_C) {
tpc->getToolBar()->crop_pressed ();
return true;
}
else if (event->keyval==GDK_s || event->keyval==GDK_S) {
tpc->getToolBar()->stra_pressed ();
return true;
}
else if (event->keyval==GDK_n || event->keyval==GDK_N) {
tpc->getToolBar()->hand_pressed ();
return true;
}
else
return false;
}
void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) {
if (whoChangedIt!=EDITOR)
tpc->profileChange (&openThm->getProcParams(), rtengine::EvProfileChangeNotification, "Profile Changed in Browser");
}
rtengine::IImage16* EditorPanel::processImage () {
rtengine::procparams::ProcParams pparams;
ipc->getParams (&pparams);
rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
int err = 0;
ProgressDialog<rtengine::IImage16*>* pdproc = new ProgressDialog<rtengine::IImage16*> (M("PROGRESSDLG_PROCESSING"));
rtengine::IImage16* img;
pdproc->setFunc (sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, pdproc->getProgressListener()), &img);
pdproc->start ();
delete pdproc;
return img;
}
BatchQueueEntry* EditorPanel::createBatchQueueEntry () {
rtengine::procparams::ProcParams pparams;
ipc->getParams (&pparams);
rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams);
int prevh = options.maxThumbnailHeight;
int prevw = prevh;
guint8* prev = NULL;//(guint8*) previewHandler->getImagePreview (prevw, prevh);
return new BatchQueueEntry (job, pparams, openThm->getFileName(), prev, prevw, prevh, openThm);
}
int EditorPanel::saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded) {
Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
if (findNewNameIfNeeded) {
int tries = 1;
while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) {
fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
tries++;
}
if (tries==1000)
return -1000;
}
ProgressDialog<int>* pdsave = new ProgressDialog<int> (M("PROGRESSDLG_SAVING"));
img->setSaveProgressListener (pdsave->getProgressListener());
int err;
if (sf.format=="tif")
pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits), &err);
else if (sf.format=="png")
pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsPNG), fileName, sf.pngCompression, sf.pngBits), &err);
else if (sf.format=="jpg")
pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsJPEG), fileName, sf.jpegQuality), &err);
pdsave->start ();
delete pdsave;
fname = fileName;
return err;
}
void EditorPanel::saveAsPressed () {
// obtaining short name without extension
saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName())));
saveAsDialog->run ();
Glib::ustring fname = saveAsDialog->getFileName ();
if (fname=="")
return;
SaveFormat sf = saveAsDialog->getFormat ();
if (getExtension (fname)!=sf.format)
fname = fname + "." + sf.format;
if (saveAsDialog->getImmediately ()) {
// check if it exists
if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) {
Glib::ustring msg_ = Glib::ustring("<b>") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + "</b>";
Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
int response = msgd.run ();
if (response==Gtk::RESPONSE_NO)
return;
}
// save image
rtengine::IImage16* img = processImage ();
int err = 0;
if (img) {
fname = removeExtension (fname);
err = saveImage (img, fname, sf, false);
img->free ();
if (!err) {
openThm->imageDeveloped ();
// save processing parameters, if needed
if (sf.saveParams) {
rtengine::procparams::ProcParams pparams;
ipc->getParams (&pparams);
pparams.save (removeExtension (fname) + ".out.pp2");
}
}
}
if (!img || err) {
Glib::ustring msg_ = Glib::ustring("<b>") + fname + ": Error during image saving\n</b>";
Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd.run ();
}
}
else {
BatchQueueEntry* bqe = createBatchQueueEntry ();
bqe->outFileName = fname;
bqe->saveFormat = saveAsDialog->getFormat ();
parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ());
}
// ask parent to redraw file browser
// ... or does it automatically when the tab is switched to it
}
void EditorPanel::queueImgPressed () {
saveProfile ();
parent->addBatchQueueJob (createBatchQueueEntry ());
}
void EditorPanel::sendToGimpPressed () {
// develop image
rtengine::IImage16* img = processImage ();
if (img) {
// get file name base
Glib::ustring shortname = removeExtension (Glib::path_get_basename (openThm->getFileName()));
Glib::ustring dirname = Glib::get_tmp_dir ();
Glib::ustring filename = Glib::build_filename (dirname, shortname);
SaveFormat sf;
sf.format = "tif";
sf.tiffBits = 16;
int err = saveImage (img, filename, sf, true);
img->free ();
if (!err) {
bool success=false;
Glib::ustring cmdLine;
try {
// start gimp
if (options.editorToSendTo==1) {
#ifdef _WIN32
cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), "gimp-win-remote") + "\" gimp-2.4.exe" + " \"" + filename + "\"";
#else
cmdLine = Glib::ustring("gimp-remote ") + " \"" + filename + "\"";
#endif
try {
printf ("command line: |%s|\n", Glib::filename_from_utf8(cmdLine).c_str());
Glib::spawn_command_line_async (Glib::filename_from_utf8(cmdLine));
success = true;
}
catch (const Glib::SpawnError&) {
#ifdef _WIN32
int ver = 12;
while (!success && ver) {
cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), Glib::ustring::compose("gimp-2.%1.exe",ver)) + "\" \"" + filename + "\"";
ver--;
printf ("command line: |%s|\n", Glib::filename_from_utf8(cmdLine).c_str());
try {
Glib::spawn_command_line_async (Glib::filename_from_utf8(cmdLine));
success = true;
}
catch (const Glib::SpawnError&) {
success = false;
}
}
#else
cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\"";
printf ("command line: |%s|\n", Glib::filename_from_utf8(cmdLine).c_str());
try {
Glib::spawn_command_line_async (Glib::filename_from_utf8(cmdLine));
success = true;
}
catch (const Glib::SpawnError&) {
success = false;
}
#endif
}
}
else if (options.editorToSendTo==2) {
cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir,"Photoshop.exe") + "\" \"" + filename + "\"";
printf ("command line: |%s|\n", Glib::filename_from_utf8(cmdLine).c_str());
Glib::spawn_command_line_async (Glib::filename_from_utf8(cmdLine));
success = true;
}
else if (options.editorToSendTo==3) {
cmdLine = Glib::ustring("\"") + options.customEditorProg + "\" \"" + filename + "\"";
printf ("command line: |%s|\n", Glib::filename_from_utf8(cmdLine).c_str());
Glib::spawn_command_line_async (Glib::filename_from_utf8(cmdLine));
success = true;
}
}
catch (const Glib::SpawnError&) {
success = false;
}
if (!success) {
Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd->set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY"));
msgd->set_title (M("MAIN_BUTTON_SENDTOEDITOR"));
msgd->run ();
delete msgd;
}
}
}
}
void EditorPanel::saveOptions () {
options.historyPanelWidth = hpanedl->get_position ();
options.toolPanelWidth = vboxright->get_width ();
}
void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {
if (beforeIpc) {
ProcParams* pparams = beforeIpc->getParamsForUpdate (rtengine::EvProfileChanged);
*pparams = params;
beforeIpc->paramsUpdateReady ();
}
}
void EditorPanel::beforeAfterToggled () {
removeIfThere (beforeAfterBox, beforeBox, false);
removeIfThere (afterBox, afterLabel, false);
if (beforeIarea) {
if (beforeIpc)
beforeIpc->stopProcessing ();
iarea->setBeforeAfterViews (NULL, iarea);
delete beforeIarea;
beforeIarea = NULL;
if (beforeIpc)
beforeIpc->setPreviewImageListener (NULL);
delete beforePreviewHandler;
beforePreviewHandler = NULL;
if (beforeIpc)
rtengine::StagedImageProcessor::destroy (beforeIpc);
beforeIpc = NULL;
}
if (beforeAfter->get_active ()) {
beforeIarea = new ImageAreaPanel ();
beforeLabel = Gtk::manage (new Gtk::Label ());
beforeLabel->set_markup ("<b>Before:</b>");
beforeBox = Gtk::manage (new Gtk::VBox ());
beforeBox->pack_start (*beforeLabel, Gtk::PACK_SHRINK, 2);
beforeBox->pack_start (*beforeIarea);
afterLabel = Gtk::manage (new Gtk::Label ());
afterLabel->set_markup ("<b>After:</b>");
afterBox->pack_start (*afterLabel, Gtk::PACK_SHRINK, 2);
afterBox->reorder_child (*afterLabel, 0);
beforeAfterBox->pack_start (*beforeBox);
beforeAfterBox->reorder_child (*beforeBox, 0);
beforeAfterBox->show_all ();
beforePreviewHandler = new PreviewHandler ();
isrc->increaseRef ();
beforeIpc = rtengine::StagedImageProcessor::create (isrc);
beforeIpc->setPreviewScale (10);
beforeIpc->setPreviewImageListener (beforePreviewHandler);
beforeIarea->imageArea->setPreviewHandler (beforePreviewHandler);
beforeIarea->imageArea->setImProcCoordinator (beforeIpc);
iarea->setBeforeAfterViews (beforeIarea, iarea);
beforeIarea->setBeforeAfterViews (beforeIarea, iarea);
rtengine::procparams::ProcParams params;
if (history->getBeforeLineParams (params))
historyBeforeLineChanged (params);
}
}

141
rtgui/editorpanel.h Executable file
View File

@@ -0,0 +1,141 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _EDITORPANEL_
#define _EDITORPANEL_
#include <gtkmm.h>
#include <imageareapanel.h>
#include <toolpanelcoord.h>
#include <profilepanel.h>
#include <rtengine.h>
#include <history.h>
#include <histogrampanel.h>
#include <thumbnail.h>
#include <saveasdlg.h>
#include <batchqueueentry.h>
#include <thumbnaillistener.h>
#include <navigator.h>
class EditorPanel;
struct EditorPanelIdleHelper {
EditorPanel* epanel;
bool destroyed;
int pending;
};
class RTWindow;
class EditorPanel : public Gtk::VBox,
public PParamsChangeListener,
public rtengine::ProgressListener,
public ThumbnailListener,
public HistoryBeforeLineListener {
protected:
Gtk::Label *progressLabel;
Gtk::ToggleButton* info;
Gtk::ToggleButton* hidehp;
Gtk::ToggleButton* beforeAfter;
Gtk::HPaned* hpanedl;
Gtk::HPaned* hpanedr;
Gtk::HBox* statusBox;
Gtk::Image* red;
Gtk::Image* green;
Gtk::VBox* leftbox, *vboxright;
Gtk::Button* queueimg;
Gtk::Button* saveimgas;
Gtk::Button* sendtogimp;
ImageAreaPanel* iarea;
PreviewHandler* previewHandler;
PreviewHandler* beforePreviewHandler; // for the before-after view
Navigator* navigator;
ImageAreaPanel* beforeIarea; // for the before-after view
Gtk::VBox* beforeBox;
Gtk::VBox* afterBox;
Gtk::Label* beforeLabel;
Gtk::Label* afterLabel;
Gtk::HBox* beforeAfterBox;
ProfilePanel* profilep;
History* history;
HistogramPanel* histogramPanel;
ToolPanelCoordinator* tpc;
RTWindow* parent;
SaveAsDialog* saveAsDialog;
Thumbnail* openThm;
rtengine::InitialImage* isrc;
rtengine::StagedImageProcessor* ipc;
rtengine::StagedImageProcessor* beforeIpc; // for the before-after view
EditorPanelIdleHelper* epih;
void open (Thumbnail* tmb, rtengine::InitialImage* isrc);
void close ();
rtengine::IImage16* processImage ();
BatchQueueEntry* createBatchQueueEntry ();
int saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded);
public:
static rtengine::InitialImage* loadImage (Thumbnail* tmb);
EditorPanel (Thumbnail* tmb, rtengine::InitialImage* isrc);
virtual ~EditorPanel ();
bool beforeClosing ();
void on_realize ();
void setParent (RTWindow* p) { parent = p; }
// progresslistener interface
void setProgressState (int state);
void error (Glib::ustring descr);
void refreshProcessingState (bool state); // this is called by setProcessingState in the gtk thread
void displayError (Glib::ustring descr); // this is called by error in the gtk thread
// PParamsChangeListener interface
void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL);
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
// HistoryBeforeLineListener
void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params);
// event handlers
void info_toggled ();
void hideHistoryActivated ();
void beforeAfterToggled ();
void saveAsPressed ();
void queueImgPressed ();
void sendToGimpPressed ();
void saveProfile ();
Glib::ustring getShortName ();
Glib::ustring getFileName ();
bool handleShortcutKey (GdkEventKey* event);
void saveOptions ();
};
#endif

44
rtgui/exiffiltersettings.cc Executable file
View File

@@ -0,0 +1,44 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <exiffiltersettings.h>
ExifFilterSettings::ExifFilterSettings () {
clear ();
}
void ExifFilterSettings::clear () {
fnumberFrom = 100;
fnumberTo = 0;
shutterFrom = 100;
shutterTo = 0;
isoFrom = 100000000;
isoTo = 0;
focalFrom = 1e8;
focalTo = 0;
lenses.clear ();
cameras.clear ();
filterFNumber = false;
filterShutter = false;
filterFocalLen = false;
filterISO = false;
filterCamera = false;
filterLens = false;
}

51
rtgui/exiffiltersettings.h Executable file
View File

@@ -0,0 +1,51 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _EXIFFILTERSETTINGS_
#define _EXIFFILTERSETTINGS_
#include <set>
#include <string>
class ExifFilterSettings {
public:
std::set<std::string> cameras;
std::set<std::string> lenses;
double fnumberFrom;
double fnumberTo;
double shutterFrom;
double shutterTo;
double focalFrom;
double focalTo;
int isoFrom;
int isoTo;
bool filterFNumber;
bool filterShutter;
bool filterFocalLen;
bool filterISO;
bool filterCamera;
bool filterLens;
ExifFilterSettings ();
void clear ();
};
#endif

568
rtgui/exifpanel.cc Executable file
View File

@@ -0,0 +1,568 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <exifpanel.h>
using namespace rtengine;
using namespace rtengine::procparams;
using namespace rtexif;
extern Glib::ustring argv0;
ExifPanel::ExifPanel () : idata(NULL) {
recursiveOp = true;
exifTree = Gtk::manage(new Gtk::TreeView());
scrolledWindow = Gtk::manage(new Gtk::ScrolledWindow());
exifTree->set_headers_visible(false);
exifTree->set_rules_hint(false);
exifTree->set_reorderable(false);
exifTree->set_enable_search(true);
exifTree->get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
scrolledWindow->set_border_width(2);
scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE);
scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT);
scrolledWindow->add(*exifTree);
exifTreeModel = Gtk::TreeStore::create(exifColumns);
exifTree->set_model (exifTreeModel);
delicon = Gdk::Pixbuf::create_from_file (argv0+"/images/deltags.png");
keepicon = Gdk::Pixbuf::create_from_file (argv0+"/images/addtags.png");
editicon = Gdk::Pixbuf::create_from_file (argv0+"/images/logoicon16.png");
Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name"));
Gtk::CellRendererPixbuf* render_pb = Gtk::manage(new Gtk::CellRendererPixbuf ());
Gtk::CellRendererText *render_txt = Gtk::manage(new Gtk::CellRendererText());
viewcol->pack_start (*render_pb, false);
viewcol->pack_start (*render_txt, true);
viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon);
viewcol->add_attribute (*render_txt, "markup", exifColumns.field);
render_pb->property_ypad() = 0;
render_txt->property_ypad() = 0;
render_pb->property_yalign() = 0;
render_txt->property_yalign() = 0;
exifTree->append_column (*viewcol);
Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value"));
Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText());
viewcolv->pack_start (*render_txtv, true);
viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value);
render_txtv->property_ypad() = 0;
exifTree->append_column (*viewcolv);
pack_start (*scrolledWindow);
Gtk::HBox* buttons1 = Gtk::manage(new Gtk::HBox ());
Gtk::HBox* buttons2 = Gtk::manage(new Gtk::HBox ());
remove = Gtk::manage(new Gtk::Button (M("EXIFPANEL_REMOVE")));
remove->set_image (*Gtk::manage(new Gtk::Image (delicon)));
remove->set_tooltip_text (M("EXIFPANEL_REMOVEHINT"));
buttons1->pack_start (*remove);
keep = Gtk::manage(new Gtk::Button (M("EXIFPANEL_KEEP")));
keep->set_image (*Gtk::manage(new Gtk::Image (keepicon)));
keep->set_tooltip_text (M("EXIFPANEL_KEEPHINT"));
buttons1->pack_start (*keep);
add = Gtk::manage(new Gtk::Button (M("EXIFPANEL_ADDEDIT")));
add->set_image (*Gtk::manage(new Gtk::Image (editicon)));
add->set_tooltip_text (M("EXIFPANEL_ADDEDITHINT"));
buttons1->pack_start (*add);
reset = Gtk::manage(new Gtk::Button (M("EXIFPANEL_RESET")));
reset->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID ("gtk-undo"), Gtk::IconSize (2))));
reset->set_tooltip_text (M("EXIFPANEL_RESETHINT"));
buttons2->pack_start (*reset);
resetAll = Gtk::manage(new Gtk::Button (M("EXIFPANEL_RESETALL")));
resetAll->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/gtk-undo-ltr.png")));
resetAll->set_tooltip_text (M("EXIFPANEL_RESETALLHINT"));
buttons2->pack_start (*resetAll);
pack_end (*buttons2, Gtk::PACK_SHRINK);
pack_end (*buttons1, Gtk::PACK_SHRINK);
exifTree->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &ExifPanel::exifSelectionChanged));
exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::row_activated));
remove->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::removePressed) );
keep->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::keepPressed) );
reset->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetPressed) );
resetAll->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetAllPressed) );
add->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::addPressed) );
show_all ();
}
ExifPanel::~ExifPanel () {
}
void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
changeList = pp->exif;
setImageData (idata);
applyChangeList ();
exifSelectionChanged ();
enableListener ();
}
void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) {
// updateChangeList ();
pp->exif = changeList;
}
void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
defChangeList = defParams->exif;
}
void ExifPanel::setImageData (const ImageMetaData* id) {
idata = id;
exifTreeModel->clear ();
const std::vector<Tag*>& defTags = ExifManager::getDefaultTIFFTags (NULL);
for (int i=0; i<defTags.size(); i++)
if (defTags[i]->nameToString() == "ImageWidth" || defTags[i]->nameToString() == "ImageHeight" || defTags[i]->nameToString() == "BitsPerSample")
addTag (exifTreeModel->children(), defTags[i]->nameToString(), "?", SYSTEM, false);
else
addTag (exifTreeModel->children(), defTags[i]->nameToString(), defTags[i]->valueToString(), SYSTEM, false);
if (id && id->getExifData ()) {
// id->getExifData ()->printAll ();
addDirectory (id->getExifData (), exifTreeModel->children());
}
}
Gtk::TreeModel::Children ExifPanel::addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, int action, bool editable) {
Gtk::TreeModel::Row row = *(exifTreeModel->append(root));
row[exifColumns.action] = action;
row[exifColumns.editable] = editable;
row[exifColumns.edited] = false;
row[exifColumns.field_nopango] = field;
row[exifColumns.value_nopango] = value;
row[exifColumns.orig_value] = value;
if (action==WRITE)
row[exifColumns.icon] = keepicon;
else if (action==DONTWRITE)
row[exifColumns.icon] = delicon;
if (editable) {
row[exifColumns.field] = Glib::ustring("<b>") + field + "</b>";
row[exifColumns.value] = Glib::ustring("<b>") + value + "</b>";
}
else if (action==SYSTEM) {
row[exifColumns.field] = Glib::ustring("<i>") + field + "</i>";
row[exifColumns.value] = Glib::ustring("<i>") + value + "</i>";
}
else {
row[exifColumns.field] = field;
row[exifColumns.value] = value;
}
return row.children();
}
void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root) {
for (int i=0; i<dir->getCount(); i++) {
Tag* t = ((TagDirectory*)dir)->getTagByIndex (i);
if (t->getAttrib() && t->getAttrib()->action==SYSTEM)
continue;
if (t->isDirectory())
for (int j=0; t->getDirectory(j); j++) {
Gtk::TreeModel::Children ch = addTag (root, t->nameToString (j), M("EXIFPANEL_SUBDIRECTORY"), t->getAttrib() ? t->getAttrib()->action : 0, t->getAttrib() && t->getAttrib()->editable);
addDirectory (t->getDirectory(j), ch);
}
else
addTag (root, t->nameToString (), t->valueToString (), t->getAttrib() ? t->getAttrib()->action : 0, t->getAttrib() && t->getAttrib()->editable);
}
}
void ExifPanel::exifSelectionChanged () {
Glib::RefPtr<Gtk::TreeSelection> selection = exifTree->get_selection();
std::vector<Gtk::TreeModel::Path> sel = selection->get_selected_rows();
if (sel.size()>1) {
remove->set_sensitive (1);
keep->set_sensitive (1);
reset->set_sensitive (1);
}
else if (sel.size()==1) {
Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (sel[0]);
if (iter->get_value (exifColumns.action)==SYSTEM) {
remove->set_sensitive (0);
keep->set_sensitive (0);
reset->set_sensitive (0);
}
else if (iter->children().size()>0) {
remove->set_sensitive (1);
keep->set_sensitive (1);
reset->set_sensitive (1);
}
else if (iter->get_value(exifColumns.icon)==delicon) {
remove->set_sensitive (0);
keep->set_sensitive (1);
reset->set_sensitive (1);
}
else if (iter->get_value(exifColumns.icon)==keepicon || iter->get_value(exifColumns.icon)==editicon) {
keep->set_sensitive (0);
remove->set_sensitive (1);
reset->set_sensitive (1);
}
}
else {
remove->set_sensitive (0);
keep->set_sensitive (0);
reset->set_sensitive (0);
}
}
void ExifPanel::delIt (Gtk::TreeModel::iterator iter) {
if (!iter)
return;
if (iter->get_value (exifColumns.action) != SYSTEM)
iter->set_value (exifColumns.icon, delicon);
if (recursiveOp)
for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++)
delIt (i);
}
void ExifPanel::removePressed () {
std::vector<Gtk::TreeModel::Path> sel = exifTree->get_selection()->get_selected_rows();
for (int i=0; i<sel.size(); i++)
delIt (exifTreeModel->get_iter (sel[i]));
exifSelectionChanged ();
updateChangeList ();
notifyListener ();
}
void ExifPanel::keepIt (Gtk::TreeModel::iterator iter) {
if (!iter)
return;
if (iter->get_value (exifColumns.action) != SYSTEM)
iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon);
if (recursiveOp)
for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++)
keepIt (i);
}
void ExifPanel::keepPressed () {
std::vector<Gtk::TreeModel::Path> sel = exifTree->get_selection()->get_selected_rows();
for (int i=0; i<sel.size(); i++)
keepIt (exifTreeModel->get_iter (sel[i]));
exifSelectionChanged ();
updateChangeList ();
notifyListener ();
}
/*void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) {
if (!iter)
return;
if (iter->get_value (exifColumns.action)!=SYSTEM)
iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon);
if (iter->get_value (exifColumns.edited)) {
iter->set_value (exifColumns.value, Glib::ustring("<b>") + iter->get_value(exifColumns.orig_value) + "</b>");
iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value));
iter->set_value (exifColumns.edited, false);
}
if (iter->get_value (exifColumns.action)==100)
exifTreeModel->erase (iter);
else
if (recursiveOp)
for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++)
resetIt (i);
}*/
Gtk::TreeModel::iterator ExifPanel::resetIt (Gtk::TreeModel::iterator iter) {
if (!iter)
return iter;
if (iter->get_value (exifColumns.action)!=SYSTEM)
iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon);
if (iter->get_value (exifColumns.edited)) {
iter->set_value (exifColumns.value, Glib::ustring("<b>") + iter->get_value(exifColumns.orig_value) + "</b>");
iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value));
iter->set_value (exifColumns.edited, false);
}
if (iter->get_value (exifColumns.action)==100) {
return exifTreeModel->erase (iter);
}
else
if (recursiveOp) {
Gtk::TreeModel::iterator i = iter->children().begin();
while (i && i != iter->children().end())
i = resetIt (i);
}
return ++iter;
}
void ExifPanel::resetPressed () {
std::vector<Gtk::TreeModel::Path> sel = exifTree->get_selection()->get_selected_rows();
for (int i=0; i<sel.size(); i++)
resetIt (exifTreeModel->get_iter (sel[i]));
exifSelectionChanged ();
updateChangeList ();
notifyListener ();
}
void ExifPanel::resetAllPressed () {
setImageData (idata);
changeList = defChangeList;
applyChangeList ();
exifSelectionChanged ();
notifyListener ();
}
void ExifPanel::addPressed () {
Gtk::Dialog* dialog = new Gtk::Dialog (M("EXIFPANEL_ADDTAGDLG_TITLE"), *((Gtk::Window*)get_toplevel()), true, true);
dialog->add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
dialog->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
Gtk::HBox* hb1 = new Gtk::HBox ();
Gtk::HBox* hb2 = new Gtk::HBox ();
Gtk::Label* tlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_SELECTTAG")+":");
Gtk::ComboBoxText* tcombo = new Gtk::ComboBoxText ();
tcombo->append_text ("Artist");
tcombo->append_text ("Copyright");
tcombo->append_text ("ImageDescription");
tcombo->append_text ("Exif.UserComment");
hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4);
hb1->pack_start (*tcombo);
Gtk::Label* vlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_ENTERVALUE")+":");
Gtk::Entry* ventry = new Gtk::Entry ();
hb2->pack_start (*vlabel, Gtk::PACK_SHRINK, 4);
hb2->pack_start (*ventry);
Glib::ustring sel = getSelection (true);
if (sel=="")
tcombo->set_active_text ("Exif.UserComment");
else {
tcombo->set_active_text (sel);
if (tcombo->get_active ()<0) {
tcombo->append_text (sel);
tcombo->set_active_text (sel);
}
ventry->set_text (getSelectedValue ());
}
ventry->set_activates_default (true);
dialog->set_default_response (Gtk::RESPONSE_OK);
dialog->get_vbox()->pack_start (*hb1, Gtk::PACK_SHRINK);
dialog->get_vbox()->pack_start (*hb2, Gtk::PACK_SHRINK, 4);
tlabel->show ();
tcombo->show ();
vlabel->show ();
ventry->show ();
hb1->show ();
hb2->show ();
if (dialog->run ()== Gtk::RESPONSE_OK) {
editTag (exifTreeModel->children(), tcombo->get_active_text(), ventry->get_text());
updateChangeList ();
notifyListener ();
}
delete dialog;
delete tlabel;
delete tcombo;
delete vlabel;
delete ventry;
delete hb1;
delete hb2;
}
void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value) {
Glib::ustring::size_type dp = name.find_first_of ('.');
Glib::ustring fseg = name.substr (0,dp);
// look up first segment of the path
Gtk::TreeModel::iterator iter;
for (iter = root.begin(); iter!=root.end(); iter++)
if (iter->get_value (exifColumns.field_nopango) == fseg)
break;
if (iter==root.end() && value!="#keep" && value!="#delete") {
iter = exifTreeModel->append(root);
iter->set_value (exifColumns.field_nopango, fseg);
iter->set_value (exifColumns.action, 100);
if (dp==Glib::ustring::npos) {
iter->set_value (exifColumns.value, Glib::ustring("<b>") + value + "</b>");
iter->set_value (exifColumns.value_nopango, value);
iter->set_value (exifColumns.orig_value, value);
iter->set_value (exifColumns.field, Glib::ustring("<b>") + fseg + "</b>");
iter->set_value (exifColumns.edited, true);
iter->set_value (exifColumns.editable, true);
iter->set_value (exifColumns.icon, editicon);
}
else {
iter->set_value (exifColumns.value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY")));
iter->set_value (exifColumns.value_nopango, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY")));
iter->set_value (exifColumns.field, fseg);
iter->set_value (exifColumns.icon, keepicon);
iter->set_value (exifColumns.orig_value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY")));
}
}
if (dp==Glib::ustring::npos) {
if (value=="#keep" && iter->get_value (exifColumns.action)!=SYSTEM)
iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon);
else if (value=="#delete" && iter->get_value (exifColumns.action)!=SYSTEM)
iter->set_value (exifColumns.icon, delicon);
else {
iter->set_value (exifColumns.value, Glib::ustring("<b>") + value + "</b>");
iter->set_value (exifColumns.value_nopango, value);
iter->set_value (exifColumns.edited, true);
iter->set_value (exifColumns.icon, editicon);
}
}
else
editTag (iter->children(), name.substr (dp+1, Glib::ustring::npos), value);
}
Glib::ustring ExifPanel::getSelectedValue () {
Glib::RefPtr<Gtk::TreeSelection> selection = exifTree->get_selection();
std::vector<Gtk::TreeModel::Path> rows = selection->get_selected_rows();
if (rows.size()!=1)
return "";
Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]);
if (iter)
return iter->get_value (exifColumns.value_nopango);
return "";
}
Glib::ustring ExifPanel::getSelection (bool onlyeditable) {
Glib::RefPtr<Gtk::TreeSelection> selection = exifTree->get_selection();
std::vector<Gtk::TreeModel::Path> rows = selection->get_selected_rows();
if (rows.size()!=1)
return "";
Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]);
Glib::ustring ret = "";
bool first = true;
bool editable = false;
while (iter) {
if (first)
ret = iter->get_value (exifColumns.field_nopango);
else
ret = iter->get_value (exifColumns.field_nopango) + "." + ret;
editable = iter->get_value (exifColumns.editable);
iter = iter->parent ();
first = false;
}
if (!editable && onlyeditable)
return "";
return ret;
}
void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string prefix) {
if (prefix!="")
prefix = prefix + ".";
Gtk::TreeModel::iterator iter;
for (iter = root.begin(); iter!=root.end(); iter++) {
if (iter->get_value (exifColumns.edited) == true) {
ExifPair ec;
ec.field = prefix + iter->get_value (exifColumns.field_nopango);
ec.value = iter->get_value (exifColumns.value_nopango);
changeList.push_back (ec);
}
else if (iter->get_value (exifColumns.action) == WRITE && iter->get_value (exifColumns.icon) == delicon) {
ExifPair ec;
ec.field = prefix + iter->get_value (exifColumns.field_nopango);
ec.value = "#delete";
changeList.push_back (ec);
}
else if (iter->get_value (exifColumns.action) == DONTWRITE && iter->get_value (exifColumns.icon) == keepicon) {
ExifPair ec;
ec.field = prefix + iter->get_value (exifColumns.field_nopango);
ec.value = "#keep";
changeList.push_back (ec);
}
if (iter->get_value (exifColumns.icon) == keepicon)
updateChangeList (iter->children(), prefix + iter->get_value (exifColumns.field_nopango));
}
}
void ExifPanel::updateChangeList () {
changeList.clear ();
updateChangeList (exifTreeModel->children(), "");
}
void ExifPanel::applyChangeList () {
for (int i=0; i<changeList.size(); i++)
editTag (exifTreeModel->children(), changeList[i].field, changeList[i].value);
}
void ExifPanel::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) {
Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (path);
if (iter) {
if (iter->children().size()>0)
if (exifTree->row_expanded (path))
exifTree->collapse_row (path);
else
exifTree->expand_row (path, false);
else if (iter->get_value (exifColumns.editable))
addPressed ();
}
}
void ExifPanel::notifyListener () {
if (listener)
listener->panelChanged (EvExif, M("HISTORY_CHANGED"));
}

97
rtgui/exifpanel.h Executable file
View File

@@ -0,0 +1,97 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _EXIFPANEL_
#define _EXIFPANEL_
#include <gtkmm.h>
#include <toolpanel.h>
class ExifPanel : public Gtk::VBox, public ToolPanel {
private:
const rtengine::ImageMetaData* idata;
int fullw, fullh, cx, cy, cw, ch;
bool crenabled;
std::vector<rtengine::procparams::ExifPair> changeList;
std::vector<rtengine::procparams::ExifPair> defChangeList;
bool recursiveOp;
class ExifColumns : public Gtk::TreeModelColumnRecord {
public:
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
Gtk::TreeModelColumn<Glib::ustring> field;
Gtk::TreeModelColumn<Glib::ustring> field_nopango;
Gtk::TreeModelColumn<Glib::ustring> value;
Gtk::TreeModelColumn<Glib::ustring> value_nopango;
Gtk::TreeModelColumn<Glib::ustring> orig_value;
Gtk::TreeModelColumn<int> action; // = 0: dont write to output, =1: write to output, =2: chagned by RT (not editable/deletable), =3: new addition
Gtk::TreeModelColumn<bool> editable;
Gtk::TreeModelColumn<bool> edited;
ExifColumns() { add(field); add(value); add(icon); add(action); add(edited); add(field_nopango); add(value_nopango); add(editable); add(orig_value); }
};
Glib::RefPtr<Gdk::Pixbuf> delicon;
Glib::RefPtr<Gdk::Pixbuf> keepicon;
Glib::RefPtr<Gdk::Pixbuf> editicon;
ExifColumns exifColumns;
Gtk::TreeView* exifTree;
Gtk::ScrolledWindow* scrolledWindow;
Glib::RefPtr<Gtk::TreeStore> exifTreeModel;
Gtk::Button* remove;
Gtk::Button* keep;
Gtk::Button* add;
Gtk::Button* reset;
Gtk::Button* resetAll;
Gtk::TreeModel::Children addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, int action, bool editable);
void editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value);
void updateChangeList (Gtk::TreeModel::Children root, std::string prefix);
void addDirectory (const rtexif::TagDirectory* dir, Gtk::TreeModel::Children root);
Glib::ustring getSelection (bool onlyifeditable=false);
Glib::ustring getSelectedValue ();
void updateChangeList ();
void applyChangeList ();
void keepIt (Gtk::TreeModel::iterator iter);
void delIt (Gtk::TreeModel::iterator iter);
Gtk::TreeModel::iterator resetIt (Gtk::TreeModel::iterator iter);
public:
ExifPanel ();
virtual ~ExifPanel ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setImageData (const rtengine::ImageMetaData* id);
void exifSelectionChanged ();
void removePressed ();
void keepPressed ();
void resetPressed ();
void resetAllPressed ();
void addPressed ();
void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
void notifyListener ();
};
#endif

112
rtgui/favoritbrowser.cc Executable file
View File

@@ -0,0 +1,112 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <favoritbrowser.h>
FavoritBrowser::FavoritBrowser () : listener (NULL), lastSelectedDir ("") {
scrollw = Gtk::manage (new Gtk::ScrolledWindow ());
scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ("Favorite Folders"));
frame->add (*scrollw);
pack_start (*frame);
treeView = Gtk::manage (new Gtk::TreeView ());
scrollw->add (*treeView);
favoritModel = Gtk::ListStore::create (favoritColumns);
treeView->set_model (favoritModel);
treeView->set_headers_visible (false);
Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column ("icon"));
Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf());
iviewcol->pack_start (*iconCR, false);
iviewcol->add_attribute (*iconCR, "gicon", 0);
treeView->append_column (*iviewcol);
treeView->append_column ("text", favoritColumns.shortdir);
treeView->set_tooltip_column (2);
treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FavoritBrowser::selectionChanged));
add = Gtk::manage (new Gtk::Button ("Add"));
del = Gtk::manage (new Gtk::Button ("Del"));
add->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_MENU)));
del->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REMOVE, Gtk::ICON_SIZE_MENU)));
Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ());
buttonBox->pack_start (*add);
buttonBox->pack_start (*del);
pack_start (*buttonBox, Gtk::PACK_SHRINK, 2);
add->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::addPressed));
del->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::delPressed));
show_all ();
}
void FavoritBrowser::selectionChanged () {
Glib::RefPtr<Gtk::TreeSelection> selection = treeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter && listener)
listener->selectDir (iter->get_value (favoritColumns.fulldir));
}
void FavoritBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) {
lastSelectedDir = dirname;
}
void FavoritBrowser::addPressed () {
if (lastSelectedDir=="")
return;
// check if the dirname is already in the list. If yes, return.
Gtk::TreeModel::iterator iter = favoritModel->children ().begin();
while (iter != favoritModel->children().end()) {
if (iter->get_value (favoritColumns.fulldir) == lastSelectedDir)
return;
iter++;
}
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_parse_name (lastSelectedDir);
if (hfile) {
Glib::RefPtr<Gio::FileInfo> info = hfile->query_info ();
if (info) {
Gtk::TreeModel::Row newrow = *(favoritModel->append());
newrow[favoritColumns.shortdir] = info->get_display_name ();
newrow[favoritColumns.fulldir] = lastSelectedDir;
newrow[favoritColumns.icon] = info->get_icon ();
}
}
}
void FavoritBrowser::delPressed () {
// lookup the selected item in the bookmark
Glib::RefPtr<Gtk::TreeSelection> selection = treeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter)
favoritModel->erase (iter);
}

58
rtgui/favoritbrowser.h Executable file
View File

@@ -0,0 +1,58 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FAVORITBROWSER_
#define _FAVORITBROWSER_
#include <gtkmm.h>
#include <dirbrowserremoteinterface.h>
#include <dirselectionlistener.h>
class FavoritBrowser : public Gtk::VBox, public DirSelectionListener {
class FavoritColumns : public Gtk::TreeModel::ColumnRecord {
public:
Gtk::TreeModelColumn<Glib::RefPtr<Gio::Icon> > icon;
Gtk::TreeModelColumn<Glib::ustring> shortdir;
Gtk::TreeModelColumn<Glib::ustring> fulldir;
FavoritColumns() { add(icon); add(shortdir), add(fulldir); }
};
FavoritColumns favoritColumns;
Gtk::ScrolledWindow* scrollw;
Gtk::TreeView* treeView;
Glib::RefPtr<Gtk::ListStore> favoritModel;
DirBrowserRemoteInterface* listener;
Glib::ustring lastSelectedDir;
Gtk::Button* add;
Gtk::Button* del;
public:
FavoritBrowser ();
void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; }
void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile="");
void addPressed ();
void delPressed ();
void selectionChanged ();
};
#endif

581
rtgui/filebrowser.cc Executable file
View File

@@ -0,0 +1,581 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filebrowser.h>
#include <glibmm.h>
#include <options.h>
#include <multilangmgr.h>
#include <clipboard.h>
#include <profilestore.h>
#include <procparamchangers.h>
FileBrowser::FileBrowser ()
: tbl(NULL) {
fbih = new FileBrowserIdleHelper;
fbih->fbrowser = this;
fbih->destroyed = false;
fbih->pending = 0;
profileStore.parseProfiles ();
signal_style_changed().connect( sigc::mem_fun(*this, &FileBrowser::styleChanged) );
int p = 0;
pmenu = new Gtk::Menu ();
pmenu->attach (*(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p+1); p++;
pmenu->attach (*(develop = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESS"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[0] = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNRANK"))), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[1] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK1"))), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[2] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK2"))), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[3] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK3"))), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[4] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK4"))), 0, 1, p, p+1); p++;
pmenu->attach (*(rank[5] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK5"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++;
pmenu->attach (*(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(rename = new Gtk::MenuItem (M("FILEBROWSER_POPUPRENAME"))), 0, 1, p, p+1); p++;
pmenu->attach (*(remove = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVE"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++;
pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++;
pmenu->attach (*(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++;
pmenu->attach (*(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++;
pmenu->attach (*(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++;
pmenu->attach (*(applyprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE"))), 0, 1, p, p+1); p++;
pmenu->attach (*(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p+1); p++;
pmenu->show_all ();
pmaccelgroup = Gtk::AccelGroup::create ();
pmenu->set_accel_group (pmaccelgroup);
selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Q, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
profmenu = new Gtk::Menu ();
open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open));
for (int i=0; i<6; i++)
rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i]));
trash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), trash));
untrash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), untrash));
develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop));
rename->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rename));
remove->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), remove));
selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall));
copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof));
pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof));
partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof));
applyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applyprof));
clearprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearprof));
}
void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) {
trash->set_sensitive (false);
untrash->set_sensitive (false);
for (int i=0; i<selected.size(); i++)
if (((FileBrowserEntry*)selected[i])->thumbnail->getStage()==1) {
untrash->set_sensitive (true);
break;
}
for (int i=0; i<selected.size(); i++)
if (((FileBrowserEntry*)selected[i])->thumbnail->getStage()==0) {
trash->set_sensitive (true);
break;
}
pasteprof->set_sensitive (clipboard.hasProcParams());
partpasteprof->set_sensitive (clipboard.hasProcParams());
copyprof->set_sensitive (selected.size()==1);
clearprof->set_sensitive (selected.size()>0);
int p = 0;
Gtk::Menu* applmenu = Gtk::manage (new Gtk::Menu ());
std::vector<Glib::ustring> profnames = profileStore.getProfileNames ();
for (int i=0; i<profnames.size(); i++) {
Gtk::MenuItem* mi = Gtk::manage (new Gtk::MenuItem (profnames[i]));
applmenu->attach (*mi, 0, 1, p, p+1); p++;
mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyMenuItemActivated), profnames[i]));
mi->show ();
}
applyprof->set_submenu (*applmenu);
pmenu->popup (3, this->eventTime);
}
void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry) {
if (tbl && entry) {
std::vector<Thumbnail*> entries;
entries.push_back (((FileBrowserEntry*)entry)->thumbnail);
tbl->openRequested (entries);
}
}
struct addparams {
FileBrowserIdleHelper* fbih;
FileBrowserEntry* entry;
};
int addfl (void* data) {
addparams* ap = (addparams*) data;
FileBrowserIdleHelper* fbih = ap->fbih;
gdk_threads_enter();
if (fbih->destroyed) {
if (fbih->pending == 1)
delete fbih;
else
fbih->pending--;
delete ap->entry;
delete ap;
gdk_threads_leave ();
return 0;
}
ap->fbih->fbrowser->addEntry_ (ap->entry);
delete ap;
fbih->pending--;
gdk_threads_leave();
return 0;
}
void FileBrowser::addEntry (FileBrowserEntry* entry) {
fbih->pending++;
entry->setParent (this);
addparams* ap = new addparams;
ap->fbih = fbih;
ap->entry = entry;
g_idle_add (addfl, ap);
}
void FileBrowser::addEntry_ (FileBrowserEntry* entry) {
entry->selected = false;
entry->drawable = false;
entry->framed = editedFiles.find (entry->filename)!=editedFiles.end();
// add button set to the thumbbrowserentry
entry->addButtonSet (new FileThumbnailButtonSet (entry));
entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank());
entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()==1);
entry->getThumbButtonSet()->setButtonListener (this);
entry->resize (options.thumbSize);
// find place in abc order
std::vector<ThumbBrowserEntryBase*>::iterator i = fd.begin();
while (i!=fd.end() && *entry < *((FileBrowserEntry*)*i))
i++;
fd.insert (i, entry);
initEntry (entry);
redraw ();
}
FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) {
for (std::vector<ThumbBrowserEntryBase*>::iterator i=fd.begin(); i!=fd.end(); i++)
if ((*i)->filename==fname) {
ThumbBrowserEntryBase* entry = *i;
entry->selected = false;
fd.erase (i);
std::vector<ThumbBrowserEntryBase*>::iterator j = std::find (selected.begin(), selected.end(), entry);
if (j!=selected.end()) {
selected.erase (j);
notifySelectionListener ();
}
if (lastClicked==entry)
lastClicked = NULL;
redraw ();
return (FileBrowserEntry*)entry;
}
return NULL;
}
FileBrowserEntry* FileBrowser::findEntry (const Glib::ustring& fname) {
for (std::vector<ThumbBrowserEntryBase*>::iterator i=fd.begin(); i!=fd.end(); i++)
if ((*i)->filename==fname)
return (FileBrowserEntry*)*i;
return NULL;
}
void FileBrowser::close () {
if (fbih->pending)
fbih->destroyed = true;
else
delete fbih;
fbih = new FileBrowserIdleHelper;
fbih->fbrowser = this;
fbih->destroyed = false;
fbih->pending = 0;
for (int i=0; i<fd.size(); i++)
delete fd[i];
fd.clear ();
selected.clear ();
notifySelectionListener ();
lastClicked = NULL;
for (int i=0; i<fd.size(); i++)
((FileBrowserEntry*)fd[i])->thumbnail->decreaseRef ();
}
void FileBrowser::menuItemActivated (Gtk::MenuItem* m) {
std::vector<FileBrowserEntry*> mselected;
for (int i=0; i<selected.size(); i++)
mselected.push_back ((FileBrowserEntry*)selected[i]);
if (!tbl || (m!=selall && mselected.size()==0) )
return;
for (int i=0; i<6; i++)
if (m==rank[i]) {
rankingRequested (mselected, i);
return;
}
if (m==open) {
std::vector<Thumbnail*> entries;
for (int i=0; i<mselected.size(); i++)
entries.push_back (mselected[i]->thumbnail);
tbl->openRequested (entries);
}
else if (m==remove)
tbl->deleteRequested (mselected);
else if (m==trash)
toTrashRequested (mselected);
else if (m==untrash)
fromTrashRequested (mselected);
else if (m==develop)
tbl->developRequested (mselected);
else if (m==rename)
tbl->renameRequested (mselected);
else if (m==selall) {
lastClicked = NULL;
selected.clear ();
for (int i=0; i<fd.size(); i++)
if (checkFilter (fd[i])) {
fd[i]->selected = true;
selected.push_back (fd[i]);
}
queue_draw ();
notifySelectionListener ();
}
else if (m==copyprof)
copyProfile ();
else if (m==pasteprof)
pasteProfile ();
else if (m==partpasteprof)
partPasteProfile ();
else if (m==clearprof) {
for (int i=0; i<mselected.size(); i++)
mselected[i]->thumbnail->clearProcParams (FILEBROWSER);
queue_draw ();
}
}
void FileBrowser::copyProfile () {
if (selected.size()==1)
clipboard.setProcParams (((FileBrowserEntry*)selected[0])->thumbnail->getProcParams());
}
void FileBrowser::pasteProfile () {
std::vector<FileBrowserEntry*> mselected;
for (int i=0; i<selected.size(); i++)
mselected.push_back ((FileBrowserEntry*)selected[i]);
if (!tbl || mselected.size()==0)
return;
for (int i=0; i<mselected.size(); i++)
mselected[i]->thumbnail->setProcParams (clipboard.getProcParams(), FILEBROWSER);
queue_draw ();
}
void FileBrowser::partPasteProfile () {
std::vector<FileBrowserEntry*> mselected;
for (int i=0; i<selected.size(); i++)
mselected.push_back ((FileBrowserEntry*)selected[i]);
if (!tbl || mselected.size()==0)
return;
if (partialPasteDlg.run ()) {
for (int i=0; i<mselected.size(); i++) {
rtengine::procparams::ProcParams params = mselected[i]->thumbnail->getProcParams ();
partialPasteDlg.applyPaste (&params, &clipboard.getProcParams());
mselected[i]->thumbnail->setProcParams (params, FILEBROWSER);
}
queue_draw ();
}
partialPasteDlg.hide ();
}
bool FileBrowser::keyPressed (GdkEventKey* event) {
if ((event->keyval==GDK_C || event->keyval==GDK_c) && event->state & GDK_CONTROL_MASK) {
copyProfile ();
return true;
}
else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) {
pasteProfile ();
return true;
}
else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) {
partPasteProfile ();
return true;
}
else if (event->keyval==GDK_Delete && !(event->state & GDK_SHIFT_MASK)) {
menuItemActivated (trash);
return true;
}
else if (event->keyval==GDK_Delete && event->state & GDK_SHIFT_MASK) {
menuItemActivated (untrash);
return true;
}
else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && event->state & GDK_CONTROL_MASK) {
menuItemActivated (develop);
return true;
}
else if ((event->keyval==GDK_A || event->keyval==GDK_a) && event->state & GDK_CONTROL_MASK) {
menuItemActivated (selall);
return true;
}
return false;
}
void FileBrowser::applyMenuItemActivated (Glib::ustring ppname) {
rtengine::procparams::ProcParams* pparams = profileStore.getProfile (ppname);
if (pparams && selected.size()>0) {
for (int i=0; i<selected.size(); i++)
((FileBrowserEntry*)selected[i])->thumbnail->setProcParams (*pparams, FILEBROWSER);
queue_draw ();
}
}
void FileBrowser::applyFilter (const BrowserFilter& filter) {
this->filter = filter;
// remove items not complying the filter from the selection
bool selchanged = false;
for (int i=0; i<fd.size(); i++)
if (fd[i]->selected && !checkFilter (fd[i])) {
fd[i]->selected = false;
std::vector<ThumbBrowserEntryBase*>::iterator j = std::find (selected.begin(), selected.end(), fd[i]);
selected.erase (j);
if (lastClicked==fd[i])
lastClicked = NULL;
selchanged = true;
}
if (selchanged)
notifySelectionListener ();
redraw ();
}
bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry complies filter
FileBrowserEntry* entry = (FileBrowserEntry*)entryb;
// return false if basic filter settings are not satisfied
if (filter.showRanked[entry->thumbnail->getRank()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash))
return false;
// check exif filter
const CacheImageData* cfs = entry->thumbnail->getCacheImageData();
double tol = 0.01;
double tol2 = 1e-8;
if (!filter.exifFilterEnabled)
return true;
if (!cfs->exifValid)
return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0)
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0);
return
(!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))
&& (!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))
&& (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom-tol && cfs->focalLen <= filter.exifFilter.focalTo+tol))
&& (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo))
&& (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0)
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0);
}
void FileBrowser::toTrashRequested (std::vector<FileBrowserEntry*> tbe) {
for (int i=0; i<tbe.size(); i++) {
if (tbe[i]->thumbnail->getStage()==1)
continue;
tbe[i]->thumbnail->setStage (1);
if (tbe[i]->getThumbButtonSet()) {
tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
tbe[i]->getThumbButtonSet()->setInTrash (true);
}
}
applyFilter (filter);
}
void FileBrowser::fromTrashRequested (std::vector<FileBrowserEntry*> tbe) {
for (int i=0; i<tbe.size(); i++) {
if (tbe[i]->thumbnail->getStage()==0)
continue;
tbe[i]->thumbnail->setStage (0);
if (tbe[i]->getThumbButtonSet()) {
tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
tbe[i]->getThumbButtonSet()->setInTrash (false);
}
}
applyFilter (filter);
}
void FileBrowser::rankingRequested (std::vector<FileBrowserEntry*> tbe, int rank) {
for (int i=0; i<tbe.size(); i++) {
tbe[i]->thumbnail->setRank (rank);
if (tbe[i]->getThumbButtonSet())
tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank());
}
applyFilter (filter);
}
void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionData) {
if (actionCode>=0 && actionCode<=5) { // rank
std::vector<FileBrowserEntry*> tbe;
tbe.push_back ((FileBrowserEntry*)actionData);
rankingRequested (tbe, actionCode);
}
else if (actionCode==6 && tbl) { // to processin queue
std::vector<FileBrowserEntry*> tbe;
tbe.push_back ((FileBrowserEntry*)actionData);
tbl->developRequested (tbe);
}
else if (actionCode==7) { // to trash / undelete
std::vector<FileBrowserEntry*> tbe;
FileBrowserEntry* entry = (FileBrowserEntry*)actionData;
tbe.push_back (entry);
if (entry->thumbnail->getStage()==0)
toTrashRequested (tbe);
else
fromTrashRequested (tbe);
}
}
void FileBrowser::openNextImage () {
if (fd.size()>0) {
for (int i=fd.size()-1; i>=0; i--)
if (editedFiles.find (fd[i]->filename)!=editedFiles.end())
if (i<fd.size()-1 && tbl) {
std::vector<Thumbnail*> entries;
entries.push_back (((FileBrowserEntry*)fd[i+1])->thumbnail);
tbl->openRequested (entries);
return;
}
if (tbl) {
std::vector<Thumbnail*> entries;
entries.push_back (((FileBrowserEntry*)fd[0])->thumbnail);
tbl->openRequested (entries);
}
}
}
void FileBrowser::openPrevImage () {
if (fd.size()>0) {
for (int i=0; i<fd.size(); i++)
if (editedFiles.find (fd[i]->filename)!=editedFiles.end())
if (i>0 && tbl) {
std::vector<Thumbnail*> entries;
entries.push_back (((FileBrowserEntry*)fd[i-1])->thumbnail);
tbl->openRequested (entries);
return;
}
if (tbl) {
std::vector<Thumbnail*> entries;
entries.push_back (((FileBrowserEntry*)fd[fd.size()-1])->thumbnail);
tbl->openRequested (entries);
}
}
}
int redrawtb (void* data) {
((FileBrowser*)data)->_thumbRearrangementNeeded ();
return 0;
}
void FileBrowser::_thumbRearrangementNeeded () {
refreshThumbImages ();
}
void FileBrowser::thumbRearrangementNeeded () {
g_idle_add (redrawtb, this);
}
void FileBrowser::selectionChanged () {
notifySelectionListener ();
}
void FileBrowser::notifySelectionListener () {
if (tbl) {
std::vector<Thumbnail*> thm;
for (int i=0; i<selected.size(); i++)
thm.push_back (((FileBrowserEntry*)selected[i])->thumbnail);
tbl->selectionChanged (thm);
}
}
void FileBrowser::redrawNeeded (ThumbBrowserEntryBase* entry) {
if (entry->insideWindow (0, 0, internal.get_width(), internal.get_height())) {
if (!internal.isDirty ()) {
internal.setDirty ();
internal.queue_draw ();
}
}
}
void FileBrowser::redrawNeeded (LWButton* button) {
queue_draw ();
}

116
rtgui/filebrowser.h Executable file
View File

@@ -0,0 +1,116 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILEBROWSER_
#define _FILEBROWSER_
#include <gtkmm.h>
#include <thumbbrowserbase.h>
#include <exiffiltersettings.h>
#include <filebrowserentry.h>
#include <browserfilter.h>
#include <partialpastedlg.h>
class FileBrowser;
class FileBrowserEntry;
class FileBrowserListener {
public:
virtual void openRequested (std::vector<Thumbnail*> tbe) {}
virtual void developRequested (std::vector<FileBrowserEntry*> tbe) {}
virtual void renameRequested (std::vector<FileBrowserEntry*> tbe) {}
virtual void deleteRequested (std::vector<FileBrowserEntry*> tbe) {}
virtual void selectionChanged (std::vector<Thumbnail*> tbe) {}
};
struct FileBrowserIdleHelper {
FileBrowser* fbrowser;
bool destroyed;
int pending;
};
class FileBrowser : public ThumbBrowserBase, public LWButtonListener {
protected:
Gtk::MenuItem* rank[6];
Gtk::MenuItem* trash;
Gtk::MenuItem* untrash;
Gtk::MenuItem* develop;
Gtk::MenuItem* rename;
Gtk::MenuItem* remove;
Gtk::MenuItem* open;
Gtk::MenuItem* selall;
Gtk::MenuItem* copyprof;
Gtk::MenuItem* pasteprof;
Gtk::MenuItem* partpasteprof;
Gtk::MenuItem* applyprof;
Gtk::MenuItem* clearprof;
Gtk::Menu* pmenu;
Gtk::Menu* profmenu;
Glib::RefPtr<Gtk::AccelGroup> pmaccelgroup;
FileBrowserListener* tbl;
BrowserFilter filter;
PartialPasteDlg partialPasteDlg;
FileBrowserIdleHelper* fbih;
void toTrashRequested (std::vector<FileBrowserEntry*> tbe);
void fromTrashRequested (std::vector<FileBrowserEntry*> tbe);
void rankingRequested (std::vector<FileBrowserEntry*> tbe, int rank);
void notifySelectionListener ();
public:
FileBrowser ();
void addEntry (FileBrowserEntry* entry); // can be called from any thread
void addEntry_ (FileBrowserEntry* entry); // this must be executed inside the gtk thread
FileBrowserEntry* delEntry (const Glib::ustring& fname); // return the entry if found here return NULL otherwise
FileBrowserEntry* findEntry (const Glib::ustring& fname); // return the entry if found here return NULL otherwise
void close ();
void setFileBrowserListener (FileBrowserListener* l) { tbl = l; }
void menuItemActivated (Gtk::MenuItem* m);
void applyMenuItemActivated (Glib::ustring ppname);
void applyFilter (const BrowserFilter& filter);
void buttonPressed (LWButton* button, int actionCode, void* actionData);
void redrawNeeded (LWButton* button);
bool checkFilter (ThumbBrowserEntryBase* entry);
void rightClicked (ThumbBrowserEntryBase* entry);
void doubleClicked (ThumbBrowserEntryBase* entry);
bool keyPressed (GdkEventKey* event);
void openNextImage ();
void openPrevImage ();
void copyProfile ();
void pasteProfile ();
void partPasteProfile ();
void redrawNeeded (ThumbBrowserEntryBase* entry);
void thumbRearrangementNeeded ();
void _thumbRearrangementNeeded ();
void selectionChanged ();
};
#endif

555
rtgui/filebrowserentry.cc Executable file
View File

@@ -0,0 +1,555 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filebrowserentry.h>
#include <thumbbrowserbase.h>
#include <cursormanager.h>
#include <iomanip>
#include <guiutils.h>
#define CROPRESIZEBORDER 4
bool FileBrowserEntry::iconsLoaded = false;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::editedIcon;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::recentlySavedIcon;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::enqueuedIcon;
FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname)
: ThumbBrowserEntryBase (fname), thumbnail(thm), iatlistener(NULL), state(SNormal), cropgl(NULL) {
feih = new FileBrowserEntryIdleHelper;
feih->fbentry = this;
feih->destroyed = false;
feih->pending = 0;
italicstyle = thumbnail->getType() != FT_Raw;
datetimeline = thumbnail->getDateTimeString ();
exifline = thumbnail->getExifString ();
if (!iconsLoaded) {
editedIcon = Gdk::Pixbuf::create_from_file (argv0+"/images/edited.png");
recentlySavedIcon = Gdk::Pixbuf::create_from_file (argv0+"/images/saved.png");
enqueuedIcon = Gdk::Pixbuf::create_from_file (argv0+"/images/processing.png");
}
if (thm)
thm->addThumbnailListener (this);
}
FileBrowserEntry::~FileBrowserEntry () {
thumbImageUpdater.removeJobs (this);
if (thumbnail)
thumbnail->removeThumbnailListener (this);
if (feih->pending)
feih->destroyed = true;
else
delete feih;
}
void FileBrowserEntry::refreshThumbnailImage () {
if (!thumbnail)
return;
thumbImageUpdater.add (thumbnail, thumbnail->getProcParams(), preh, &updatepriority, this);
thumbImageUpdater.process ();
}
void FileBrowserEntry::calcThumbnailSize () {
if (thumbnail)
thumbnail->getThumbnailSize (prew, preh);
}
std::vector<Glib::RefPtr<Gdk::Pixbuf> > FileBrowserEntry::getIconsOnImageArea () {
std::vector<Glib::RefPtr<Gdk::Pixbuf> > ret;
if (!thumbnail)
return ret;
if (thumbnail->hasProcParams() && editedIcon)
ret.push_back (editedIcon);
if (thumbnail->isRecentlySaved() && recentlySavedIcon)
ret.push_back (recentlySavedIcon);
if (thumbnail->isEnqueued () && enqueuedIcon)
ret.push_back (enqueuedIcon);
return ret;
}
void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c) {
if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)
drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams);
else {
rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop;
if (cparams.enabled)
drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cparams);
}
}
void FileBrowserEntry::getIconSize (int& w, int& h) {
w = editedIcon->get_width ();
h = editedIcon->get_height ();
}
FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet () {
return (FileThumbnailButtonSet*)buttonSet;
}
void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt) {
refreshThumbnailImage ();
}
struct tiupdate {
FileBrowserEntryIdleHelper* feih;
rtengine::IImage8* img;
double scale;
rtengine::procparams::CropParams cropParams;
};
int fbeupdate (void* data) {
gdk_threads_enter ();
tiupdate* params = (tiupdate*)data;
FileBrowserEntryIdleHelper* feih = params->feih;
if (feih->destroyed) {
if (feih->pending == 1)
delete feih;
else
feih->pending--;
params->img->free ();
delete params;
gdk_threads_leave ();
return 0;
}
feih->fbentry->_updateImage (params->img, params->scale, params->cropParams);
feih->pending--;
gdk_threads_leave ();
delete params;
return 0;
}
void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) {
redrawRequests++;
feih->pending++;
tiupdate* param = new tiupdate ();
param->feih = feih;
param->img = img;
param->scale = scale;
param->cropParams = cropParams;
g_idle_add (fbeupdate, param);
}
void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) {
redrawRequests--;
scale = s;
this->cropParams = cropParams;
if (preh == img->getHeight ()) {
prew = img->getWidth ();
guint8* temp = preview;
preview = NULL;
delete [] temp;
temp = new guint8 [prew*preh*3];
memcpy (temp, img->getData(), prew*preh*3);
preview = temp;
updateBackBuffer ();
}
if (redrawRequests==0 && parent)
parent->redrawNeeded (this);
img->free ();
}
bool FileBrowserEntry::motionNotify (int x, int y) {
bool b = ThumbBrowserEntryBase::motionNotify (x, y);
int ix = x - startx - ofsX;
int iy = y - starty - ofsY;
if (inside (x,y))
updateCursor (ix, iy);
if (state==SRotateSelecting) {
action_x = x;
action_y = y;
parent->redrawNeeded (this);
}
else if (state==SResizeH1 && cropgl) {
int oy = cropParams.y;
cropParams.y = action_y + (y-press_y) / scale;
cropParams.h += oy - cropParams.y;
cropgl->cropHeight1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
updateBackBuffer ();
parent->redrawNeeded (this);
}
else if (state==SResizeH2 && cropgl) {
cropParams.h = action_y + (y-press_y) / scale;
cropgl->cropHeight2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
updateBackBuffer ();
parent->redrawNeeded (this);
}
else if (state==SResizeW1 && cropgl) {
int ox = cropParams.x;
cropParams.x = action_x + (x-press_x) / scale;
cropParams.w += ox - cropParams.x;
cropgl->cropWidth1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
updateBackBuffer ();
parent->redrawNeeded (this);
}
else if (state==SResizeW2 && cropgl) {
cropParams.w = action_x + (x-press_x) / scale;
cropgl->cropWidth2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
updateBackBuffer ();
parent->redrawNeeded (this);
}
else if (state==SCropMove && cropgl) {
cropParams.x = action_x + (x-press_x) / scale;
cropParams.y = action_y + (y-press_y) / scale;
cropgl->cropMoved (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
updateBackBuffer ();
parent->redrawNeeded (this);
}
else if (state==SCropSelecting && cropgl) {
int cx1 = press_x, cy1 = press_y;
int cx2 = (ix-prex) / scale, cy2 = (iy-prey) / scale;
cropgl->cropResized (cx1, cy1, cx2, cy2);
if (cx2 > cx1) {
cropParams.x = cx1;
cropParams.w = cx2 - cx1 + 1;
}
else {
cropParams.x = cx2;
cropParams.w = cx1 - cx2 + 1;
}
if (cy2 > cy1) {
cropParams.y = cy1;
cropParams.h = cy2 - cy1 + 1;
}
else {
cropParams.y = cy2;
cropParams.h = cy1 - cy2 + 1;
}
updateBackBuffer ();
parent->redrawNeeded (this);
}
return b;
}
bool FileBrowserEntry::pressNotify (int button, int type, int bstate, int x, int y) {
bool b = ThumbBrowserEntryBase::pressNotify (button, type, bstate, x, y);
ToolMode tm = iatlistener->getToolBar()->getTool ();
int ix = x - startx - ofsX;
int iy = y - starty - ofsY;
if (!b && selected && inside (x,y)) {
if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal) {
if (onArea (CropTop, ix, iy)) {
state = SResizeH1;
press_y = y;
action_y = cropParams.y;
cropgl = iatlistener->startCropEditing (thumbnail);
b = true;
}
else if (onArea (CropBottom, ix, iy)) {
state = SResizeH2;
press_y = y;
action_y = cropParams.h;
cropgl = iatlistener->startCropEditing (thumbnail);
b = true;
}
else if (onArea (CropLeft, ix, iy)) {
state = SResizeW1;
press_x = x;
action_x = cropParams.x;
cropgl = iatlistener->startCropEditing (thumbnail);
b = true;
}
else if (onArea (CropRight, ix, iy)) {
state = SResizeW2;
press_x = x;
action_x = cropParams.w;
cropgl = iatlistener->startCropEditing (thumbnail);
b = true;
}
else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, ix, iy)) {
state = SCropMove;
press_x = x;
press_y = y;
action_x = cropParams.x;
action_y = cropParams.y;
cropgl = iatlistener->startCropEditing (thumbnail);
b = true;
}
else if (onArea (CropImage, ix, iy)) {
if (tm == TMStraighten) {
state = SRotateSelecting;
press_x = x;
press_y = y;
action_x = x;
action_y = y;
rot_deg = 0;
b = true;
}
else if (tm == TMSpotWB) {
iatlistener->spotWBselected ((ix-prex)/scale, (iy-prey)/scale, thumbnail);
b = true;
}
else if (tm == TMCropSelect) {
cropgl = iatlistener->startCropEditing (thumbnail);
if (cropgl) {
state = SCropSelecting;
press_x = cropParams.x = (ix-prex) / scale;
press_y = cropParams.y = (iy-prey) / scale;
cropParams.w = cropParams.h = 1;
cropgl->cropInit (cropParams.x, cropParams.y, cropParams.w, cropParams.h);
b = true;
}
}
}
}
updateCursor (ix, iy);
}
return b;
}
bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, int y) {
bool b = ThumbBrowserEntryBase::releaseNotify (button, type, bstate, x, y);
int ix = x - startx - ofsX;
int iy = y - starty - ofsY;
if (!b) {
if (state==SRotateSelecting) {
iatlistener->rotateSelectionReady (rot_deg, thumbnail);
iatlistener->getToolBar()->setTool (TMHand);
}
else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) {
cropgl->cropManipReady ();
cropgl = NULL;
iatlistener->cropSelectionReady ();
iatlistener->getToolBar()->setTool (TMHand);
}
state = SNormal;
if (parent)
parent->redrawNeeded (this);
updateCursor (ix, iy);
}
return b;
}
bool FileBrowserEntry::onArea (CursorArea a, int x, int y) {
if (!drawable || !preview)
return false;
int x1 = (x-prex) / scale;
int y1 = (y-prey) / scale;
int cropResizeBorder = CROPRESIZEBORDER / scale;
switch (a) {
case CropImage:
return x>=prex && x<prex+prew && y>=prey && y<prey+preh;
case CropTop:
return cropParams.enabled &&
x1>cropParams.x+cropResizeBorder &&
x1<cropParams.x+cropParams.w-1-cropResizeBorder &&
y1>cropParams.y-cropResizeBorder &&
y1<cropParams.y+cropResizeBorder;
case CropBottom:
return cropParams.enabled &&
x1>cropParams.x+cropResizeBorder &&
x1<cropParams.x+cropParams.w-1-cropResizeBorder &&
y1>cropParams.y+cropParams.h-1-cropResizeBorder &&
y1<cropParams.y+cropParams.h-1+cropResizeBorder;
case CropLeft:
return cropParams.enabled &&
y1>cropParams.y+cropResizeBorder &&
y1<cropParams.y+cropParams.h-1-cropResizeBorder &&
x1>cropParams.x-cropResizeBorder &&
x1<cropParams.x+cropResizeBorder;
case CropRight:
return cropParams.enabled &&
y1>cropParams.y+cropResizeBorder &&
y1<cropParams.y+cropParams.h-1-cropResizeBorder &&
x1>cropParams.x+cropParams.w-1-cropResizeBorder &&
x1<cropParams.x+cropParams.w-1+cropResizeBorder;
case CropInside:
return cropParams.enabled &&
y1>cropParams.y &&
y1<cropParams.y+cropParams.h-1 &&
x1>cropParams.x &&
x1<cropParams.x+cropParams.w-1;
}
return false;
}
void FileBrowserEntry::updateCursor (int x, int y) {
if (!iatlistener)
return;
ToolMode tm = iatlistener->getToolBar()->getTool ();
Glib::RefPtr<Gdk::Window> w = parent->getDrawingArea ()->get_window();
if (!selected) {
cursorManager.setCursor (w, CSArrow);
return;
}
if (state==SNormal) {
if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y)))
cursorManager.setCursor (w, CSResizeHeight);
else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y)))
cursorManager.setCursor (w, CSResizeWidth);
else if (onArea (CropImage, x, y)) {
if (tm==TMHand)
cursorManager.setCursor (w, CSArrow);
else if (tm==TMSpotWB)
cursorManager.setCursor (w, CSSpotWB);
else if (tm==TMCropSelect)
cursorManager.setCursor (w, CSCropSelect);
else if (tm==TMStraighten)
cursorManager.setCursor (w, CSStraighten);
}
else
cursorManager.setCursor (w, CSArrow);
}
else if (state==SCropSelecting)
cursorManager.setCursor (w, CSCropSelect);
else if (state==SRotateSelecting)
cursorManager.setCursor (w, CSStraighten);
else if (state==SCropMove)
cursorManager.setCursor (w, CSMove);
else if (state==SResizeW1 || state==SResizeW2)
cursorManager.setCursor (w, CSResizeWidth);
else if (state==SResizeH1 || state==SResizeH2)
cursorManager.setCursor (w, CSResizeHeight);
}
void FileBrowserEntry::draw () {
ThumbBrowserEntryBase::draw ();
if (state==SRotateSelecting) {
Cairo::RefPtr<Cairo::Context> cr = parent->getDrawingArea ()->get_window()->create_cairo_context();
drawStraightenGuide (cr);
}
}
void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr<Cairo::Context> cr) {
if (action_x!=press_x || action_y!=press_y) {
double arg = (press_x-action_x) / sqrt((press_x-action_x)*(press_x-action_x)+(press_y-action_y)*(press_y-action_y));
double sol1, sol2;
double pi = M_PI;
if (press_y>action_y) {
sol1 = acos(arg)*180/pi;
sol2 = -acos(-arg)*180/pi;
}
else {
sol1 = acos(-arg)*180/pi;
sol2 = -acos(arg)*180/pi;
}
if (fabs(sol1)<fabs(sol2))
rot_deg = sol1;
else
rot_deg = sol2;
if (rot_deg<-45)
rot_deg = 90.0 + rot_deg;
else if (rot_deg>45)
rot_deg = - 90.0 + rot_deg;
}
else
rot_deg = 0;
Glib::RefPtr<Pango::Context> context = parent->getDrawingArea()->get_pango_context () ;
Pango::FontDescription fontd = context->get_font_description ();
fontd.set_weight (Pango::WEIGHT_BOLD);
fontd.set_size (8*Pango::SCALE);
context->set_font_description (fontd);
Glib::RefPtr<Pango::Layout> deglayout = parent->getDrawingArea()->create_pango_layout(Glib::ustring::compose ("%1 deg", Glib::ustring::format(std::setprecision(2), rot_deg)));
int x1 = press_x;
int y1 = press_y;
int y2 = action_y;
int x2 = action_x;
if (x2<prex+ofsX+startx) {
y2 = y1 - (double)(y1-y2)*(x1 - (prex+ofsX+startx)) / (x1-x2);
x2 = prex+ofsX+startx;
}
else if (x2>=prew+prex+ofsX+startx) {
y2 = y1 - (double)(y1-y2)*(x1 - (prew+prex+ofsX+startx-1)) / (x1-x2);
x2 = prew+prex+ofsX+startx-1;
}
if (y2<prey+ofsY+starty) {
x2 = x1 - (double)(x1-x2)*(y1 - (prey+ofsY+starty)) / (y1-y2);
y2 = prey+ofsY+starty;
}
else if (y2>=preh+prey+ofsY+starty) {
x2 = x1 - (double)(x1-x2)*(y1 - (preh+prey+ofsY+starty-1)) / (y1-y2);
y2 = preh+prey+ofsY+starty-1;
}
cr->set_line_width (1.5);
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to (x1, y1);
cr->line_to (x2, y2);
cr->stroke ();
cr->set_source_rgb (0.0, 0.0, 0.0);
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (x1, y1);
cr->line_to (x2, y2);
cr->stroke ();
if (press_x!=action_x && press_y!=action_y) {
cr->set_source_rgb (0.0, 0.0, 0.0);
cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1);
deglayout->add_to_cairo_context (cr);
cr->move_to ((x1+x2)/2+1, (y1+y2)/2-1);
deglayout->add_to_cairo_context (cr);
cr->move_to ((x1+x2)/2-1, (y1+y2)/2+1);
deglayout->add_to_cairo_context (cr);
cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1);
deglayout->add_to_cairo_context (cr);
cr->fill ();
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to ((x1+x2)/2, (y1+y2)/2);
deglayout->add_to_cairo_context (cr);
cr->fill ();
}
}

95
rtgui/filebrowserentry.h Executable file
View File

@@ -0,0 +1,95 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILEBROWSERENTRY_
#define _FILEBROWSERENTRY_
#include <gtkmm.h>
#include <thumbbrowserentrybase.h>
#include <thumbnail.h>
#include <filethumbnailbuttonset.h>
#include <thumbnaillistener.h>
#include <thumbimageupdater.h>
#include <imageareatoollistener.h>
#include <editenums.h>
#include <rtengine.h>
#include <crophandler.h>
class FileBrowserEntry;
struct FileBrowserEntryIdleHelper {
FileBrowserEntry* fbentry;
bool destroyed;
int pending;
};
class FileThumbnailButtonSet;
class FileBrowserEntry : public ThumbBrowserEntryBase,
public ThumbnailListener,
public ThumbImageUpdateListener {
double scale;
static bool iconsLoaded;
ImageAreaToolListener* iatlistener;
int press_x, press_y, action_x, action_y;
double rot_deg;
rtengine::procparams::CropParams cropParams;
CropGUIListener* cropgl;
FileBrowserEntryIdleHelper* feih;
ImgEditState state;
bool onArea (CursorArea a, int x, int y);
void updateCursor (int x, int y);
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> c);
void customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c);
public:
static Glib::RefPtr<Gdk::Pixbuf> editedIcon;
static Glib::RefPtr<Gdk::Pixbuf> recentlySavedIcon;
static Glib::RefPtr<Gdk::Pixbuf> enqueuedIcon;
Thumbnail* thumbnail;
FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname);
~FileBrowserEntry ();
void draw ();
void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; }
FileThumbnailButtonSet* getThumbButtonSet ();
void refreshThumbnailImage ();
void calcThumbnailSize ();
std::vector<Glib::RefPtr<Gdk::Pixbuf> > getIconsOnImageArea ();
void getIconSize (int& w, int& h);
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
// thumbimageupdatelistener interface
void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams);
void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread
bool motionNotify (int x, int y);
bool pressNotify (int button, int type, int bstate, int x, int y);
bool releaseNotify (int button, int type, int bstate, int x, int y);
};
#endif

799
rtgui/filecatalog.cc Executable file
View File

@@ -0,0 +1,799 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filecatalog.h>
#include <options.h>
#include <cachemanager.h>
#include <multilangmgr.h>
#include <guiutils.h>
#include <glib/gstdio.h>
#include <iostream>
#include <renamedlg.h>
#include <thumbimageupdater.h>
#define CHECKTIME 2000
extern Glib::ustring argv0;
#ifdef _WIN32
int _directoryUpdater (void* cat) {
((FileCatalog*)cat)->checkCounter++;
if (((FileCatalog*)cat)->checkCounter==2) {
gdk_threads_enter ();
((FileCatalog*)cat)->reparseDirectory ();
gdk_threads_leave ();
}
return 1;
}
#endif
FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb) : listener(NULL), fslistener(NULL), hasValidCurrentEFS(false), coarsePanel(cp), filterPanel(NULL), toolBar(tb) {
previewLoader.setPreviewLoaderListener (this);
// construct and initialize thumbnail browsers
fileBrowser = new FileBrowser();
fileBrowser->setFileBrowserListener (this);
fileBrowser->setArrangement (ThumbBrowserBase::TB_Vertical);
fileBrowser->show ();
// construct trash panel with the extra "empty trash" button
trashButtonBox = new Gtk::VBox;
Gtk::Button* emptyT = new Gtk::Button (M("FILEBROWSER_EMPTYTRASH"));
emptyT->set_tooltip_text (M("FILEBROWSER_EMPTYTRASHHINT"));
emptyT->set_image (*(new Gtk::Image (Gtk::StockID("gtk-delete"), Gtk::ICON_SIZE_BUTTON)));
emptyT->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::emptyTrash));
trashButtonBox->pack_start (*emptyT, Gtk::PACK_SHRINK, 4);
emptyT->show ();
trashButtonBox->show ();
// setup button bar
buttonBar = new Gtk::HBox ();
pack_start (*buttonBar, Gtk::PACK_SHRINK);
buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK);
bDir = new Gtk::ToggleButton ();
bDir->set_active (true);
bDir->set_image (*(new Gtk::Image (argv0+"/images/folder.png")));
bDir->set_relief (Gtk::RELIEF_NONE);
bDir->set_tooltip_text (M("FILEBROWSER_SHOWDIRHINT"));
bCateg[0] = bDir->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bDir));
buttonBar->pack_start (*bDir, Gtk::PACK_SHRINK);
buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK);
bUnRanked = new Gtk::ToggleButton ();
bUnRanked->set_active (false);
bUnRanked->set_image (*(new Gtk::Image (argv0+"/images/unrated.png")));
bUnRanked->set_relief (Gtk::RELIEF_NONE);
bUnRanked->set_tooltip_text (M("FILEBROWSER_SHOWUNRANKHINT"));
bCateg[1] = bUnRanked->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnRanked));
buttonBar->pack_start (*bUnRanked, Gtk::PACK_SHRINK);
buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK);
for (int i=0; i<5; i++) {
iranked[i] = new Gtk::Image (argv0+"/images/rated.png");
igranked[i] = new Gtk::Image (argv0+"/images/grayrated.png");
iranked[i]->show ();
igranked[i]->show ();
bRank[i] = new Gtk::ToggleButton ();
bRank[i]->set_image (*igranked[i]);
bRank[i]->set_relief (Gtk::RELIEF_NONE);
buttonBar->pack_start (*bRank[i], Gtk::PACK_SHRINK);
bCateg[i+2] = bRank[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bRank[i]));
}
bRank[0]->set_tooltip_text (M("FILEBROWSER_SHOWRANK1HINT"));
bRank[1]->set_tooltip_text (M("FILEBROWSER_SHOWRANK2HINT"));
bRank[2]->set_tooltip_text (M("FILEBROWSER_SHOWRANK3HINT"));
bRank[3]->set_tooltip_text (M("FILEBROWSER_SHOWRANK4HINT"));
bRank[4]->set_tooltip_text (M("FILEBROWSER_SHOWRANK5HINT"));
buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK);
bTrash = new Gtk::ToggleButton ();
bTrash->set_image (*(new Gtk::Image (Gtk::StockID("gtk-delete"), Gtk::ICON_SIZE_SMALL_TOOLBAR)));
bTrash->set_relief (Gtk::RELIEF_NONE);
bTrash->set_tooltip_text (M("FILEBROWSER_SHOWTRASHHINT"));
bCateg[7] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash));
buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK);
buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK);
categoryButtons[0] = bDir;
categoryButtons[1] = bUnRanked;
for (int i=0; i<5; i++)
categoryButtons[i+2] = bRank[i];
categoryButtons[7] = bTrash;
// thumbnail zoom
Gtk::HBox* zoomBox = new Gtk::HBox ();
zoomInButton = new Gtk::Button ();
zoomInButton->set_image (*(new Gtk::Image (Gtk::StockID("gtk-zoom-in"), Gtk::ICON_SIZE_SMALL_TOOLBAR)));
zoomInButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomIn));
zoomInButton->set_relief (Gtk::RELIEF_NONE);
zoomInButton->set_tooltip_text (M("FILEBROWSER_ZOOMINHINT"));
zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK);
zoomOutButton = new Gtk::Button ();
zoomOutButton->set_image (*(new Gtk::Image (Gtk::StockID("gtk-zoom-out"), Gtk::ICON_SIZE_SMALL_TOOLBAR)));
zoomOutButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomOut));
zoomOutButton->set_relief (Gtk::RELIEF_NONE);
zoomOutButton->set_tooltip_text (M("FILEBROWSER_ZOOMOUTHINT"));
zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK);
// add default panel
hBox = new Gtk::HBox ();
hBox->show ();
hBox->pack_end (*fileBrowser);
fileBrowser->applyFilter (getFilter());
pack_start (*hBox);
buttonBar2 = new Gtk::HBox ();
pack_end (*buttonBar2, Gtk::PACK_SHRINK);
progressBar = new Gtk::ProgressBar ();
buttonBar2->pack_start (*progressBar, Gtk::PACK_SHRINK, 4);
progressBar->set_size_request (-1, 16);
buttonBar->pack_start (*zoomBox, Gtk::PACK_SHRINK);
buttonBar->pack_end (*coarsePanel, Gtk::PACK_SHRINK);
buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4);
buttonBar->pack_end (*toolBar, Gtk::PACK_SHRINK);
buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4);
enabled = true;
lastScrollPos = 0;
for (int i=0; i<8; i++) {
hScrollPos[i] = 0;
vScrollPos[i] = 0;
}
selectedDirectory = "";
#ifdef _WIN32
wdMonitor = NULL;
checkCounter = 2;
g_timeout_add (CHECKTIME, _directoryUpdater, this);
#endif
}
void FileCatalog::on_realize() {
Gtk::VBox::on_realize();
Pango::FontDescription fontd = get_pango_context()->get_font_description ();
fileBrowser->get_pango_context()->set_font_description (fontd);
// batchQueue->get_pango_context()->set_font_description (fontd);
}
void FileCatalog::closeDir () {
if (filterPanel)
filterPanel->set_sensitive (false);
#ifndef _WIN32
if (dirMonitor)
dirMonitor->cancel ();
#else
if (wdMonitor) {
delete wdMonitor;
wdMonitor = NULL;
}
#endif
// terminate thumbnail preview loading
previewLoader.terminate ();
// terminate thumbnail updater
thumbImageUpdater.terminate ();
// remove entries
fileBrowser->close ();
fileNameList.clear ();
dirEFS.clear ();
hasValidCurrentEFS = false;
selectedDirectory = "";
redrawAll ();
}
std::vector<Glib::ustring> FileCatalog::getFileList () {
std::vector<Glib::ustring> names;
try {
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (selectedDirectory);
if (!dir)
return names;
// FILE enumerator api leaks memory. Fixed in glibmm 2.18.1. Waiting for new release...
Glib::RefPtr<Gio::FileEnumerator> dirList = dir->enumerate_children ();
if (!dirList)
return names;
for (Glib::RefPtr<Gio::FileInfo> info = dirList->next_file(); info; info = dirList->next_file())
names.push_back (Glib::build_filename (selectedDirectory, info->get_name()));
}
catch (Glib::Exception& ex) {
std::cout << ex.what();
}
return names;
}
void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) {
try {
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (dirname);
if (!dir)
return;
closeDir ();
previewsToLoad = 0;
previewsLoaded = 0;
// if openfile exists, we have to open it first (it is a command line argument)
if (openfile!="")
addAndOpenFile (openfile);
selectedDirectory = dir->get_parse_name();
fileNameList = getFileList ();
for (int i=0; i<fileNameList.size(); i++) {
Glib::RefPtr<Gio::File> f = Gio::File::create_for_path(fileNameList[i]);
if (f->get_parse_name() != openfile) // if we opened a file at the beginning dont add it again
checkAndAddFile (f);
}
_refreshProgressBar ();
previewLoader.process ();
#ifndef _WIN32
dirMonitor = dir->monitor_directory ();
dirMonitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::on_dir_changed), false));
#else
wdMonitor = new WinDirMonitor (selectedDirectory, this);
#endif
}
catch (Glib::Exception& ex) {
std::cout << ex.what();
}
}
void FileCatalog::_refreshProgressBar () {
// check if progress bar is visible
/* Glib::ListHandle<Gtk::Widget*> list = buttonBar2->get_children ();
Glib::ListHandle<Gtk::Widget*>::iterator i = list.begin ();
for (; i!=list.end() && *i!=progressBar; i++);
if (i==list.end()) {
buttonBar2->pack_start (*progressBar, Gtk::PACK_SHRINK, 4);
buttonBar2->reorder_child (*progressBar, 2);
}
*/
progressBar->show ();
if (previewsToLoad>0)
progressBar->set_fraction ((double)previewsLoaded / previewsToLoad);
else
progressBar->set_fraction (1.0);
}
int refreshpb (void* data) {
gdk_threads_enter ();
((FileCatalog*)data)->_refreshProgressBar ();
gdk_threads_leave ();
return 0;
}
void FileCatalog::previewReady (FileBrowserEntry* fdn) {
// put it into the "full directory" browser
fdn->setImageAreaToolListener (iatlistener);
fileBrowser->addEntry (fdn);
// update exif filter settings (minimal & maximal values of exif tags, cameras, lenses, etc...)
const CacheImageData* cfs = fdn->thumbnail->getCacheImageData();
if (cfs->exifValid) {
if (cfs->fnumber < dirEFS.fnumberFrom)
dirEFS.fnumberFrom = cfs->fnumber;
if (cfs->fnumber > dirEFS.fnumberTo)
dirEFS.fnumberTo = cfs->fnumber;
if (cfs->shutter < dirEFS.shutterFrom)
dirEFS.shutterFrom = cfs->shutter;
if (cfs->shutter > dirEFS.shutterTo)
dirEFS.shutterTo = cfs->shutter;
if (cfs->iso>0 && cfs->iso < dirEFS.isoFrom)
dirEFS.isoFrom = cfs->iso;
if (cfs->iso>0 && cfs->iso > dirEFS.isoTo)
dirEFS.isoTo = cfs->iso;
if (cfs->focalLen < dirEFS.focalFrom)
dirEFS.focalFrom = cfs->focalLen;
if (cfs->focalLen > dirEFS.focalTo)
dirEFS.focalTo = cfs->focalLen;
}
dirEFS.cameras.insert (cfs->camera);
dirEFS.lenses.insert (cfs->lens);
previewsLoaded++;
g_idle_add (refreshpb, this);
}
int prevfinished (void* data) {
gdk_threads_enter();
((FileCatalog*)data)->_previewsFinished ();
gdk_threads_leave();
return 0;
}
void FileCatalog::_previewsFinished () {
redrawAll ();
previewsToLoad = 0;
previewsLoaded = 0;
// removeIfThere (buttonBar2, progressBar);
progressBar->hide ();
if (filterPanel) {
filterPanel->set_sensitive (true);
filterPanel->setFilter (currentEFS);
}
}
void FileCatalog::previewsFinished () {
if (!hasValidCurrentEFS)
currentEFS = dirEFS;
g_idle_add (prevfinished, this);
}
void PreviewLoader::remove (Glib::ustring fname) {
std::list<DirEntry>::iterator i;
for (i=jqueue.begin(); i!=jqueue.end(); i++)
if (i->fullName==fname)
break;
if (i!=jqueue.end())
jqueue.erase (i);
}
void PreviewLoader::start () {
jqueue.sort ();
}
void PreviewLoader::process (DirEntry& current) {
if (Glib::file_test (current.fullName, Glib::FILE_TEST_EXISTS)) {
Thumbnail* tmb = cacheMgr.getEntry (current.fullName);
if (tmb && pl)
pl->previewReady (new FileBrowserEntry (tmb, current.fullName));
}
}
void PreviewLoader::end () {
if (pl)
pl->previewsFinished ();
}
void FileCatalog::setEnabled (bool e) {
enabled = e;
}
void FileCatalog::redrawAll () {
fileBrowser->queue_draw ();
}
void FileCatalog::refreshAll () {
fileBrowser->refreshThumbImages ();
}
void FileCatalog::_openImage (std::vector<Thumbnail*> tmb) {
if (enabled && listener!=NULL) {
previewLoader.stop ();
thumbImageUpdater.stop ();
for (int i=0; i<tmb.size(); i++) {
if (editedFiles.find (tmb[i]->getFileName())==editedFiles.end())
listener->fileSelected (tmb[i]);
tmb[i]->decreaseRef ();
}
previewLoader.process ();
thumbImageUpdater.process ();
}
}
struct FCOIParams {
FileCatalog* catalog;
std::vector<Thumbnail*> tmb;
};
int fcopenimg (void* p) {
gdk_threads_enter ();
FCOIParams* params = (FCOIParams*)p;
params->catalog->_openImage (params->tmb);
delete params;
gdk_threads_leave ();
return 0;
}
void FileCatalog::openRequested (std::vector<Thumbnail*> tmb) {
FCOIParams* params = new FCOIParams;
params->catalog = this;
params->tmb = tmb;
for (int i=0; i<tmb.size(); i++)
tmb[i]->increaseRef ();
g_idle_add (fcopenimg, params);
}
void FileCatalog::deleteRequested (std::vector<FileBrowserEntry*> tbe) {
if (tbe.size()==0)
return;
Gtk::MessageDialog msd (M("FILEBROWSER_DELETEDLGLABEL"), false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
msd.set_secondary_text(Glib::ustring::compose (M("FILEBROWSER_DELETEDLGMSG"), tbe.size()));
if (msd.run()==Gtk::RESPONSE_YES) {
for (int i=0; i<tbe.size(); i++) {
Glib::ustring fname = tbe[i]->filename;
// remove from browser
FileBrowserEntry* t = fileBrowser->delEntry (fname);
// t->thumbnail->decreaseRef ();
delete t;
// remove from cache
cacheMgr.deleteEntry (fname);
// delete from file system
::g_remove (fname.c_str());
// delete .pp2 if found
::g_remove (Glib::ustring(fname+".pp2").c_str());
::g_remove (Glib::ustring(removeExtension(fname)+".pp2").c_str());
// delete .thm file
::g_remove (Glib::ustring(removeExtension(fname)+".thm").c_str());
::g_remove (Glib::ustring(removeExtension(fname)+".THM").c_str());
}
redrawAll ();
}
}
void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe) {
if (listener) {
thumbImageUpdater.stop ();
for (int i=0; i<tbe.size(); i++) {
rtengine::procparams::ProcParams params = tbe[i]->thumbnail->getProcParams();
rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (tbe[i]->filename, tbe[i]->thumbnail->getType()==FT_Raw, params);
double tmpscale;
rtengine::IImage8* img = tbe[i]->thumbnail->processThumbImage (params, options.maxThumbnailHeight, tmpscale);
if (img) {
int pw = img->getWidth ();
int ph = img->getHeight ();
guint8* prev = new guint8 [pw*ph*3];
memcpy (prev, img->getData (), pw*ph*3);
listener->addBatchQueueJob (new BatchQueueEntry (pjob, params, tbe[i]->filename, prev, pw, ph, tbe[i]->thumbnail));
}
else {
int pw, ph;
tbe[i]->thumbnail->getThumbnailSize (pw, ph);
listener->addBatchQueueJob (new BatchQueueEntry (pjob, params, tbe[i]->filename, NULL, pw, ph, tbe[i]->thumbnail));
}
}
thumbImageUpdater.process ();
}
}
void FileCatalog::renameRequested (std::vector<FileBrowserEntry*> tbe) {
RenameDialog* renameDlg = new RenameDialog ((Gtk::Window*)get_toplevel());
for (int i=0; i<tbe.size(); i++) {
renameDlg->initName (Glib::path_get_basename (tbe[i]->filename), tbe[i]->thumbnail->getCacheImageData());
Glib::ustring ofname = tbe[i]->filename;
Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename);
Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename);
if (renameDlg->run ()== Gtk::RESPONSE_OK) {
Glib::ustring nBaseName = renameDlg->getNewName ();
// if path has directory components, exit
if (Glib::path_get_dirname (nBaseName) != ".")
continue;
// if no extension is given, concatenate the extension of the original file
Glib::ustring ext = getExtension (nBaseName);
if (ext=="")
nBaseName += "." + getExtension (baseName);
Glib::ustring nfname = Glib::build_filename (dirName, nBaseName);
if (!::g_rename (ofname.c_str(), nfname.c_str())) {
cacheMgr.renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname);
reparseDirectory ();
}
renameDlg->hide ();
}
}
delete renameDlg;
/* // ask for new file name
Gtk::Dialog dialog (M("FILEBROWSER_RENAMEDLGLABEL"), *((Gtk::Window*)get_toplevel()), true, true);
dialog.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
dialog.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
Gtk::Label l;
dialog.get_vbox()->pack_start (l, Gtk::PACK_SHRINK);
Gtk::Entry nfentry;
dialog.get_vbox()->pack_start (nfentry, Gtk::PACK_SHRINK);
dialog.get_vbox()->show_all ();
nfentry.set_activates_default (true);
dialog.set_default_response (Gtk::RESPONSE_OK);
for (int i=0; i<tbe.size(); i++) {
Glib::ustring ofname = tbe[i]->filename;
Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename);
Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename);
l.set_markup (Glib::ustring("<big><b>") + Glib::ustring::compose (M("FILEBROWSER_RENAMEDLGMSG"), baseName) + Glib::ustring("</b></big>"));
nfentry.set_text (baseName);
nfentry.select_region (0, baseName.size());
if (dialog.run ()== Gtk::RESPONSE_OK) {
Glib::ustring nBaseName = nfentry.get_text ();
// if path has directory components, exit
if (Glib::path_get_dirname (nBaseName) != ".")
continue;
// if no extension is given, concatenate the extension of the original file
if (nBaseName.find ('.')==nBaseName.npos) {
int lastdot = baseName.find_last_of ('.');
nBaseName += "." + (lastdot!=Glib::ustring::npos ? baseName.substr (lastdot+1) : "");
}
Glib::ustring nfname = Glib::build_filename (dirName, nBaseName);
if (!::g_rename (ofname.c_str(), nfname.c_str())) {
cacheMgr.renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname);
// the remaining part (removing old and adding new entry) is done by the directory monitor
reparseDirectory ();
// on_dir_changed (Gio::File::create_for_path (nfname), Gio::File::create_for_path (nfname), Gio::FILE_MONITOR_EVENT_CHANGED, true);
}
}
}
*/
}
void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) {
for (int i=0; i<8; i++)
bCateg[i].block (true);
fileBrowser->getScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]);
// seek the one pressed
for (int i=0; i<8; i++) {
categoryButtons[i]->set_active (categoryButtons[i]==b);
if (categoryButtons[i]==b)
lastScrollPos = i;
}
// change the images of the buttons to reflect current ranking
for (int i=0; i<5; i++)
bRank[i]->set_image (*igranked[i]);
for (int i=0; i<5; i++)
if (b==bRank[i])
for (int j=0; j<=i; j++)
bRank[j]->set_image (*iranked[j]);
fileBrowser->applyFilter (getFilter ());
// rearrange panels according to the selected filter
removeIfThere (hBox, trashButtonBox);
if (bTrash->get_active ())
hBox->pack_start (*trashButtonBox, Gtk::PACK_SHRINK, 4);
hBox->queue_draw ();
fileBrowser->setScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]);
for (int i=0; i<8; i++)
bCateg[i].block (false);
}
BrowserFilter FileCatalog::getFilter () {
BrowserFilter filter;
filter.showRanked[0] = bDir->get_active() || bUnRanked->get_active () || bTrash->get_active ();
for (int i=1; i<=5; i++)
filter.showRanked[i] = bDir->get_active() || bRank[i-1]->get_active () || bTrash->get_active ();
filter.showTrash = bDir->get_active() || bTrash->get_active ();
filter.showNotTrash = !bTrash->get_active ();
if (!filterPanel)
filter.exifFilterEnabled = false;
else {
if (!hasValidCurrentEFS)
filter.exifFilter = dirEFS;
else
filter.exifFilter = currentEFS;
filter.exifFilterEnabled = filterPanel->isEnabled ();
}
return filter;
}
void FileCatalog::filterChanged () {
fileBrowser->applyFilter (getFilter());
}
int FileCatalog::reparseDirectory () {
if (selectedDirectory=="")
return 0;
if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) {
closeDir ();
return 0;
}
std::vector<Glib::ustring> nfileNameList = getFileList ();
// check if a thumbnailed file has been deleted
const std::vector<ThumbBrowserEntryBase*>& t = fileBrowser->getEntries ();
std::vector<Glib::ustring> fileNamesToDel;
for (int i=0; i<t.size(); i++)
if (!Glib::file_test (t[i]->filename, Glib::FILE_TEST_EXISTS))
fileNamesToDel.push_back (t[i]->filename);
for (int i=0; i<fileNamesToDel.size(); i++) {
delete fileBrowser->delEntry (fileNamesToDel[i]);
cacheMgr.deleteEntry (fileNamesToDel[i]);
}
// check if a new file has been added
for (int i=0; i<nfileNameList.size(); i++) {
bool found = false;
for (int j=0; j<fileNameList.size(); j++)
if (nfileNameList[i]==fileNameList[j]) {
found = true;
break;
}
if (!found) {
previewLoader.stop ();
checkAndAddFile (Gio::File::create_for_parse_name (nfileNameList[i]));
_refreshProgressBar ();
previewLoader.process ();
}
}
fileNameList = nfileNameList;
return 1;
}
#ifdef _WIN32
void FileCatalog::winDirChanged () {
checkCounter = 0;
}
#endif
void FileCatalog::on_dir_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, bool internal) {
if (!internal)
gdk_threads_enter();
if (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED)
reparseDirectory ();
if (!internal)
gdk_threads_leave();
}
void FileCatalog::checkAndAddFile (Glib::RefPtr<Gio::File> file) {
if (!file)
return;
Glib::RefPtr<Gio::FileInfo> info = file->query_info();
if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) {
int lastdot = info->get_name().find_last_of ('.');
Glib::ustring ext = lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "";
// look up if it is supported
for (int j=0; j<options.parseExtensions.size(); j++)
// if supported, add it to the loader queue
if (options.parseExtensions[j].casefold() == ext.casefold() && options.parseExtensionsEnabled[j]) {
previewLoader.add (DirEntry (file->get_parse_name()));
previewsToLoad++;
break;
}
}
}
void FileCatalog::addAndOpenFile (const Glib::ustring& fname) {
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path (fname);
if (!file)
return;
Glib::RefPtr<Gio::FileInfo> info = file->query_info();
int lastdot = info->get_name().find_last_of ('.');
Glib::ustring ext = lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "";
// look up if it is supported
for (int j=0; j<options.parseExtensions.size(); j++)
if (options.parseExtensions[j].casefold() == ext.casefold() && options.parseExtensionsEnabled[j]) {
// if supported, load thumbnail first
Thumbnail* tmb = cacheMgr.getEntry (file->get_parse_name());
if (tmb) {
FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name());
previewReady (entry);
// open the file
FCOIParams* params = new FCOIParams;
params->catalog = this;
params->tmb.push_back (tmb);
tmb->increaseRef ();
g_idle_add (fcopenimg, params);
}
break;
}
}
void FileCatalog::emptyTrash () {
const std::vector<ThumbBrowserEntryBase*> t = fileBrowser->getEntries ();
std::vector<FileBrowserEntry*> toDel;
for (int i=0; i<t.size(); i++)
if (((FileBrowserEntry*)t[i])->thumbnail->getStage()==1)
toDel.push_back (((FileBrowserEntry*)t[i]));
deleteRequested (toDel);
}
void FileCatalog::zoomIn () {
bool pLoad = previewLoader.runs();
if (pLoad)
previewLoader.stop ();
fileBrowser->zoomIn ();
if (pLoad)
previewLoader.process ();
}
void FileCatalog::zoomOut () {
bool pLoad = previewLoader.runs();
if (pLoad)
previewLoader.stop ();
fileBrowser->zoomOut ();
if (pLoad)
previewLoader.process ();
}
void FileCatalog::refreshEditedState (const std::set<Glib::ustring>& efiles) {
editedFiles = efiles;
fileBrowser->refreshEditedState (efiles);
}
void FileCatalog::selectionChanged (std::vector<Thumbnail*> tbe) {
if (fslistener)
fslistener->selectionChanged (tbe);
}
void FileCatalog::exifFilterChanged () {
currentEFS = filterPanel->getFilter ();
hasValidCurrentEFS = true;
fileBrowser->applyFilter (getFilter ());
}
void FileCatalog::setFilterPanel (FilterPanel* fpanel) {
filterPanel = fpanel;
filterPanel->set_sensitive (false);
filterPanel->setFilterPanelListener (this);
}

191
rtgui/filecatalog.h Executable file
View File

@@ -0,0 +1,191 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILECATALOG_
#define _FILECATALOG_
#ifdef _WIN32
#include <windirmonitor.h>
#endif
#include <dirselectionlistener.h>
#include <filebrowser.h>
#include <procthread.h>
#include <exiffiltersettings.h>
#include <giomm.h>
#include <fileselectionlistener.h>
#include <set>
#include <fileselectionchangelistener.h>
#include <coarsepanel.h>
#include <toolbar.h>
#include <filterpanel.h>
class PreviewLoaderListener {
public:
virtual void previewReady (FileBrowserEntry* fd) {}
virtual void previewsFinished () {}
};
class DirEntry {
public:
Glib::ustring fullName;
DirEntry (const Glib::ustring& n) : fullName (n) {}
bool operator< (DirEntry& other) {
return fullName.casefold() < other.fullName.casefold();
}
};
class PreviewLoader : public ProcessingThread<DirEntry> {
protected:
PreviewLoaderListener* pl;
public:
PreviewLoader () : pl(NULL) { ProcessingThread<DirEntry>(); }
void setPreviewLoaderListener (PreviewLoaderListener* p) { pl = p; }
void start ();
void process () { ProcessingThread<DirEntry>::process (); }
void process (DirEntry& current);
void remove (Glib::ustring fname);
void end ();
};
class FileCatalog : public Gtk::VBox,
public DirSelectionListener,
public PreviewLoaderListener,
public FilterPanelListener,
public FileBrowserListener
#ifdef _WIN32
, public WinDirChangeListener
#endif
{
// thumbnail browsers
FileBrowser* fileBrowser;
Gtk::HBox* hBox;
Glib::ustring selectedDirectory;
bool enabled;
PreviewLoader previewLoader;
FileSelectionListener* listener;
FileSelectionChangeListener* fslistener;
ImageAreaToolListener* iatlistener;
Gtk::HBox* buttonBar;
Gtk::HBox* buttonBar2;
Gtk::ToggleButton* bDir;
Gtk::ToggleButton* bUnRanked;
Gtk::ToggleButton* bRank[5];
Gtk::ToggleButton* bTrash;
Gtk::ToggleButton* categoryButtons[8];
sigc::connection bCateg[8];
Gtk::Image* iranked[5], *igranked[5];
double hScrollPos[8];
double vScrollPos[8];
int lastScrollPos;
Gtk::VBox* trashButtonBox;
Gtk::Button* zoomInButton;
Gtk::Button* zoomOutButton;
ExifFilterSettings dirEFS;
ExifFilterSettings currentEFS;
bool hasValidCurrentEFS;
FilterPanel* filterPanel;
Glib::RefPtr<Gio::FileMonitor> dirMonitor;
Gtk::ProgressBar* progressBar;
int previewsToLoad;
int previewsLoaded;
#ifdef _WIN32
WinDirMonitor* wdMonitor;
public:
int checkCounter;
void winDirChanged ();
private:
#endif
std::vector<Glib::ustring> fileNameList;
std::set<Glib::ustring> editedFiles;
void addAndOpenFile (const Glib::ustring& fname);
void checkAndAddFile (Glib::RefPtr<Gio::File> info);
std::vector<Glib::ustring> getFileList ();
BrowserFilter getFilter ();
public:
CoarsePanel* coarsePanel;
ToolBar* toolBar;
FileCatalog (CoarsePanel* cp, ToolBar* tb);
void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile="");
void closeDir ();
void refreshEditedState (const std::set<Glib::ustring>& efiles);
// previewloaderlistener interface
void previewReady (FileBrowserEntry* fdn);
void previewsFinished ();
void _previewsFinished ();
void _refreshProgressBar ();
// filterpanel interface
void exifFilterChanged ();
Glib::ustring lastSelectedDir () { return selectedDirectory; }
void setEnabled (bool e); // if not enabled, it does not open image
void redrawAll ();
void refreshAll ();
void openRequested (std::vector<Thumbnail*> tbe);
void deleteRequested (std::vector<FileBrowserEntry*> tbe);
void developRequested (std::vector<FileBrowserEntry*> tbe);
void renameRequested (std::vector<FileBrowserEntry*> tbe);
void selectionChanged (std::vector<Thumbnail*> tbe);
void emptyTrash ();
void setFileSelectionListener (FileSelectionListener* l) { listener = l; }
void setFileSelectionChangeListener (FileSelectionChangeListener* l) { fslistener = l; }
void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; }
void setFilterPanel (FilterPanel* fpanel);
void categoryButtonToggled (Gtk::ToggleButton* b);
void filterChanged ();
void runFilterDialog ();
void on_realize();
void on_dir_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, bool internal);
int reparseDirectory ();
void _openImage (std::vector<Thumbnail*> tmb);
void zoomIn ();
void zoomOut ();
void openNextImage () { fileBrowser->openNextImage(); }
void openPrevImage () { fileBrowser->openPrevImage(); }
};
#endif

186
rtgui/filepanel.cc Executable file
View File

@@ -0,0 +1,186 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filepanel.h>
#include <rtwindow.h>
int fbinit (void* data) {
gdk_threads_enter ();
((FilePanel*)data)->init ();
gdk_threads_leave ();
return 0;
}
FilePanel::FilePanel () : parent(NULL) {
dirpaned = new Gtk::HPaned ();
dirpaned->set_position (options.dirBrowserWidth);
dirBrowser = new DirBrowser ();
placesBrowser = new PlacesBrowser ();
recentBrowser = new RecentBrowser ();
placespaned = new Gtk::VPaned ();
placespaned->set_position (options.dirBrowserHeight);
Gtk::VBox* obox = Gtk::manage (new Gtk::VBox ());
obox->pack_start (*recentBrowser, Gtk::PACK_SHRINK, 4);
obox->pack_start (*dirBrowser);
placespaned->pack1 (*placesBrowser, false, true);
placespaned->pack2 (*obox, true, true);
dirpaned->pack1 (*placespaned, Gtk::SHRINK);
tpc = new BatchToolPanelCoordinator (this);
fileCatalog = new FileCatalog (tpc->coarse, tpc->getToolBar());
dirpaned->pack2 (*fileCatalog, Gtk::EXPAND|Gtk::SHRINK);
placesBrowser->setDirBrowserRemoteInterface (dirBrowser);
recentBrowser->setDirBrowserRemoteInterface (dirBrowser);
dirBrowser->addDirSelectionListener (fileCatalog);
dirBrowser->addDirSelectionListener (recentBrowser);
dirBrowser->addDirSelectionListener (placesBrowser);
fileCatalog->setFileSelectionListener (this);
rightBox = new Gtk::HBox ();
rightNotebook = new Gtk::Notebook ();
Gtk::VBox* taggingBox = new Gtk::VBox ();
history = new History (false);
tpc->addPParamsChangeListener (history);
history->setProfileChangeListener (tpc);
Gtk::ScrolledWindow* sFilterPanel = new Gtk::ScrolledWindow();
filterPanel = new FilterPanel ();
sFilterPanel->add (*filterPanel);
sFilterPanel->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
fileCatalog->setFilterPanel (filterPanel);
fileCatalog->setImageAreaToolListener (tpc);
//------------------
rightNotebook->set_tab_pos (Gtk::POS_LEFT);
Gtk::Label* devLab = new Gtk::Label ("Develop");
devLab->set_angle (90);
Gtk::Label* filtLab = new Gtk::Label ("Filter");
filtLab->set_angle (90);
Gtk::Label* tagLab = new Gtk::Label ("Tagging");
tagLab->set_angle (90);
Gtk::VPaned* tpcPaned = new Gtk::VPaned ();
tpcPaned->pack1 (*tpc->toolPanelNotebook, true, true);
tpcPaned->pack2 (*history, true, true);
rightNotebook->append_page (*tpcPaned, *devLab);
rightNotebook->append_page (*sFilterPanel, *filtLab);
rightNotebook->append_page (*taggingBox, *tagLab);
rightBox->pack_start (*rightNotebook);
pack1(*dirpaned, true, true);
pack2(*rightBox, false, true);
fileCatalog->setFileSelectionChangeListener (tpc);
fileCatalog->setFileSelectionListener (this);
g_idle_add (fbinit, this);
show_all ();
}
void FilePanel::on_realize () {
Gtk::HPaned::on_realize ();
rightBox->set_size_request (options.browserToolPanelWidth, -1);
}
void FilePanel::init () {
dirBrowser->fillDirTree ();
placesBrowser->refreshPlacesList ();
if (argv1!="")
dirBrowser->open (argv1);
else {
if (options.startupDir==STARTUPDIR_HOME)
dirBrowser->open (Glib::get_home_dir());
else if (options.startupDir==STARTUPDIR_CURRENT)
dirBrowser->open (argv0);
else if (options.startupDir==STARTUPDIR_CUSTOM || options.startupDir==STARTUPDIR_LAST)
dirBrowser->open (options.startupPath);
}
}
bool FilePanel::fileSelected (Thumbnail* thm) {
if (!parent)
return false;
// try to open the file
bool succ = false;
fileCatalog->setEnabled (false);
rtengine::InitialImage* isrc = EditorPanel::loadImage (thm);
if (isrc) {
EditorPanel* epanel = Gtk::manage (new EditorPanel (thm, isrc));
parent->addEditorPanel (epanel);
succ = true;
}
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 ();
}
fileCatalog->setEnabled (true);
return succ;
}
void FilePanel::saveOptions () {
options.dirBrowserWidth = dirpaned->get_position ();
options.dirBrowserHeight = placespaned->get_position ();
options.browserToolPanelWidth = rightBox->get_width ();
if (options.startupDir==STARTUPDIR_LAST && fileCatalog->lastSelectedDir ()!="")
options.startupPath = fileCatalog->lastSelectedDir ();
fileCatalog->closeDir ();
}
void FilePanel::open (const Glib::ustring& d) {
if (Glib::file_test (d, Glib::FILE_TEST_IS_DIR))
dirBrowser->open (d.c_str());
else if (Glib::file_test (d, Glib::FILE_TEST_EXISTS))
dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d));
}
bool FilePanel::addBatchQueueJob (BatchQueueEntry* bqe) {
if (parent)
parent->addBatchQueueJob (bqe);
}
void FilePanel::optionsChanged () {
tpc->optionsChanged ();
fileCatalog->refreshAll ();
}

74
rtgui/filepanel.h Executable file
View File

@@ -0,0 +1,74 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILEPANEL_
#define _FILEPANEL_
#include <gtkmm.h>
#include <batchtoolpanelcoord.h>
#include <filecatalog.h>
#include <dirbrowser.h>
#include <fileselectionlistener.h>
#include <placesbrowser.h>
#include <recentbrowser.h>
#include <pparamschangelistener.h>
#include <history.h>
#include <filterpanel.h>
class RTWindow;
class FilePanel : public Gtk::HPaned,
public FileSelectionListener,
public PParamsChangeListener
{
protected:
Gtk::VPaned* placespaned;
Gtk::HPaned* dirpaned;
DirBrowser* dirBrowser;
PlacesBrowser* placesBrowser;
RecentBrowser* recentBrowser;
FileCatalog* fileCatalog; // filecatalog is the file browser with the button bar above it
Gtk::HBox* rightBox;
BatchToolPanelCoordinator* tpc;
History* history;
FilterPanel* filterPanel;
RTWindow* parent;
Gtk::Notebook* rightNotebook;
public:
FilePanel ();
void on_realize ();
void setParent (RTWindow* p) { parent = p; }
void init (); // dont call it directly, the constructor calls it as idle source
void open (const Glib::ustring& d); // open a file or a directory
void refreshEditedState (const std::set<Glib::ustring>& efiles) { fileCatalog->refreshEditedState (efiles); }
// call this before closeing rt: it saves file browser relating things into options
void saveOptions ();
// interface fileselectionlistener
bool fileSelected (Thumbnail* thm);
bool addBatchQueueJob (BatchQueueEntry* bqe);
void optionsChanged ();
};
#endif

View File

@@ -0,0 +1,31 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILESELECTIONCHANGELISTENER_
#define _FILESELECTIONCHANGELISTENER_
#include <thumbnail.h>
class FileSelectionChangeListener {
public:
virtual void selectionChanged (const std::vector<Thumbnail*>& selected) {}
};
#endif

33
rtgui/fileselectionlistener.h Executable file
View File

@@ -0,0 +1,33 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILESELECTIONLISTENER_
#define _FILESELECTIONLISTENER_
#include <thumbnail.h>
#include <batchqueueentry.h>
class FileSelectionListener {
public:
virtual bool fileSelected (Thumbnail* thm) {}
virtual bool addBatchQueueJob (BatchQueueEntry* bqe) {}
};
#endif

68
rtgui/filethumbnailbuttonset.cc Executable file
View File

@@ -0,0 +1,68 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filethumbnailbuttonset.h>
#include <multilangmgr.h>
extern Glib::ustring argv0;
bool FileThumbnailButtonSet::iconsLoaded = false;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::rankIcon;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::gRankIcon;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::unRankIcon;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::trashIcon;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::unTrashIcon;
Cairo::RefPtr<Cairo::ImageSurface> FileThumbnailButtonSet::processIcon;
FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) {
if (!iconsLoaded) {
unRankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/unrated.png");
rankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/rated.png");
gRankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/grayrated.png");
trashIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/trash.png");
unTrashIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/undelete.png");
processIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/processing.png");
iconsLoaded = true;
}
add (new LWButton (unRankIcon, 0, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPUNRANK")));
for (int i=0; i<5; i++)
add (new LWButton (rankIcon, i+1, myEntry, LWButton::Left));
add (new LWButton (processIcon, 6, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPPROCESS")));
add (new LWButton (trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPTRASH")));
buttons[1]->setToolTip (M("FILEBROWSER_POPUPRANK1"));
buttons[2]->setToolTip (M("FILEBROWSER_POPUPRANK2"));
buttons[3]->setToolTip (M("FILEBROWSER_POPUPRANK3"));
buttons[4]->setToolTip (M("FILEBROWSER_POPUPRANK4"));
buttons[5]->setToolTip (M("FILEBROWSER_POPUPRANK5"));
}
void FileThumbnailButtonSet::setRank (int stars) {
for (int i=1; i<=5; i++)
buttons[i]->setIcon (i<=stars ? rankIcon : gRankIcon);
}
void FileThumbnailButtonSet::setInTrash (bool inTrash) {
buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon);
buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH"));
}

45
rtgui/filethumbnailbuttonset.h Executable file
View File

@@ -0,0 +1,45 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILETHUMBNAILBUTTONSET_
#define _FILETHUMBNAILBUTTONSET_
#include <lwbuttonset.h>
#include <gtkmm.h>
#include <filebrowserentry.h>
class FileBrowserEntry;
class FileThumbnailButtonSet : public LWButtonSet {
static bool iconsLoaded;
public:
static Cairo::RefPtr<Cairo::ImageSurface> rankIcon;
static Cairo::RefPtr<Cairo::ImageSurface> gRankIcon;
static Cairo::RefPtr<Cairo::ImageSurface> unRankIcon;
static Cairo::RefPtr<Cairo::ImageSurface> trashIcon;
static Cairo::RefPtr<Cairo::ImageSurface> unTrashIcon;
static Cairo::RefPtr<Cairo::ImageSurface> processIcon;
FileThumbnailButtonSet (FileBrowserEntry* myEntry);
void setRank (int stars);
void setInTrash (bool inTrash);
};
#endif

210
rtgui/filterpanel.cc Executable file
View File

@@ -0,0 +1,210 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <filterpanel.h>
#include <multilangmgr.h>
#include <rtengine.h>
using namespace rtengine;
FilterPanel::FilterPanel () : listener (NULL) {
set_border_width (4);
enabled = Gtk::manage (new Gtk::CheckButton ("Enable Metadata Filters"));
pack_start (*enabled, Gtk::PACK_SHRINK, 2);
pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2);
enaFNumber = Gtk::manage (new Gtk::CheckButton (M("EXIFFILTER_APERTURE")+":"));
Gtk::VBox* fnvb = Gtk::manage(new Gtk::VBox ());
Gtk::HBox* fnhb = Gtk::manage(new Gtk::HBox ());
fnvb->pack_start (*enaFNumber, Gtk::PACK_SHRINK, 0);
fnumberFrom = Gtk::manage(new Gtk::Entry ());
fnumberTo = Gtk::manage(new Gtk::Entry ());
fnhb->pack_start (*fnumberFrom, true, true, 2);
fnhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4);
fnhb->pack_start (*fnumberTo, true, true, 2);
fnvb->pack_start (*fnhb, Gtk::PACK_SHRINK, 0);
pack_start (*fnvb, Gtk::PACK_SHRINK, 4);
enaShutter = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_SHUTTER")+":"));
Gtk::VBox* svb = Gtk::manage(new Gtk::VBox ());
Gtk::HBox* shb = Gtk::manage(new Gtk::HBox ());
svb->pack_start (*enaShutter, Gtk::PACK_SHRINK, 0);
shutterFrom = Gtk::manage(new Gtk::Entry ());
shutterTo = Gtk::manage(new Gtk::Entry ());
shb->pack_start (*shutterFrom, true, true, 2);
shb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4);
shb->pack_start (*shutterTo, true, true, 2);
svb->pack_start (*shb, Gtk::PACK_SHRINK, 0);
pack_start (*svb, Gtk::PACK_SHRINK, 4);
enaISO = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_ISO")+":"));
Gtk::VBox* ivb = Gtk::manage(new Gtk::VBox ());
Gtk::HBox* ihb = Gtk::manage(new Gtk::HBox ());
ivb->pack_start (*enaISO, Gtk::PACK_SHRINK, 0);
isoFrom = Gtk::manage(new Gtk::Entry ());
isoTo = Gtk::manage(new Gtk::Entry ());
ihb->pack_start (*isoFrom, true, true, 2);
ihb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4);
ihb->pack_start (*isoTo, true, true, 2);
ivb->pack_start (*ihb, Gtk::PACK_SHRINK, 0);
pack_start (*ivb, Gtk::PACK_SHRINK, 4);
enaFocalLen = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FOCALLEN")+":"));
Gtk::VBox* fvb = Gtk::manage(new Gtk::VBox ());
Gtk::HBox* fhb = Gtk::manage(new Gtk::HBox ());
fvb->pack_start (*enaFocalLen, Gtk::PACK_SHRINK, 0);
focalFrom = Gtk::manage(new Gtk::Entry ());
focalTo = Gtk::manage(new Gtk::Entry ());
fhb->pack_start (*focalFrom, true, true, 2);
fhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4);
fhb->pack_start (*focalTo, true, true, 2);
fvb->pack_start (*fhb, Gtk::PACK_SHRINK, 0);
pack_start (*fvb, Gtk::PACK_SHRINK, 4);
enaCamera = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_CAMERA")+":"));
Gtk::VBox* cvb = Gtk::manage(new Gtk::VBox ());
cvb->pack_start (*enaCamera, Gtk::PACK_SHRINK, 0);
camera = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE));
camera->set_headers_visible (false);
Gtk::ScrolledWindow* scamera = Gtk::manage(new Gtk::ScrolledWindow());
scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scamera->add(*camera);
cvb->pack_start (*scamera, Gtk::PACK_SHRINK, 0);
pack_start (*cvb, Gtk::PACK_SHRINK, 4);
enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS")+":"));
Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ());
lvb->pack_start (*enaLens, Gtk::PACK_SHRINK, 0);
lens = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE));
lens->set_headers_visible (false);
Gtk::ScrolledWindow* slens = Gtk::manage(new Gtk::ScrolledWindow());
slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
slens->add(*lens);
lvb->pack_start (*slens, Gtk::PACK_SHRINK, 0);
pack_start (*lvb, Gtk::PACK_SHRINK, 4);
conns = 0;
sChange[conns++] = fnumberFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = fnumberTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = shutterFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = shutterTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = isoFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = isoTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = focalFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = focalTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = camera->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = lens->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged));
sChange[conns++] = enaFNumber->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enaShutter->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enaFocalLen->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enaISO->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enaCamera->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enaLens->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
sChange[conns++] = enabled->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) );
set_size_request (0, -1);
show_all ();
}
void FilterPanel::setFilter (ExifFilterSettings& defefs) {
curefs = defefs;
for (int i=0; i<conns; i++)
sChange[i].block (true);
// enaFNumber->set_active (curefs.filterFNumber);
fnumberFrom->set_text (ImageMetaData::apertureToString (curefs.fnumberFrom));
fnumberTo->set_text (ImageMetaData::apertureToString (curefs.fnumberTo));
// enaShutter->set_active (curefs.filterShutter);
shutterFrom->set_text (ImageMetaData::shutterToString (curefs.shutterFrom));
shutterTo->set_text (ImageMetaData::shutterToString (curefs.shutterTo));
// enaISO->set_active (curefs.filterISO);
isoFrom->set_text (Glib::ustring::format (curefs.isoFrom));
isoTo->set_text (Glib::ustring::format (curefs.isoTo));
// enaFocalLen->set_active (curefs.filterFocalLen);
focalFrom->set_text (Glib::ustring::format (curefs.focalFrom));
focalTo->set_text (Glib::ustring::format (curefs.focalTo));
// enaCamera->set_active (curefs.filterCamera);
Glib::RefPtr<Gtk::TreeSelection> cselection = camera->get_selection ();
int j=0;
for (std::set<std::string>::iterator i = defefs.cameras.begin(); i!=defefs.cameras.end(); i++, j++) {
camera->append_text (*i);
if (curefs.cameras.count (*i)>0)
cselection->select (camera->get_model()->children()[j]);
}
// enaLens->set_active (curefs.filterLens);
Glib::RefPtr<Gtk::TreeSelection> lselection = lens->get_selection ();
j = 0;
for (std::set<std::string>::iterator i = defefs.lenses.begin(); i!=defefs.lenses.end(); i++, j++) {
lens->append_text (*i);
if (curefs.lenses.count (*i)>0)
lselection->select (lens->get_model()->children()[j]);
}
for (int i=0; i<conns; i++)
sChange[i].block (false);
}
bool FilterPanel::isEnabled () {
return enabled->get_active () && is_sensitive();
}
ExifFilterSettings FilterPanel::getFilter () {
ExifFilterSettings efs;
efs.fnumberFrom = atof (fnumberFrom->get_text().c_str());
efs.fnumberTo = atof (fnumberTo->get_text().c_str());
efs.focalFrom = atof (focalFrom->get_text().c_str());
efs.focalTo = atof (focalTo->get_text().c_str());
efs.isoFrom = atoi (isoFrom->get_text().c_str());
efs.isoTo = atoi (isoTo->get_text().c_str());
efs.shutterFrom = ImageMetaData::shutterFromString (shutterFrom->get_text());
efs.shutterTo = ImageMetaData::shutterFromString (shutterTo->get_text());
efs.filterFNumber = enaFNumber->get_active ();
efs.filterShutter = enaShutter->get_active ();
efs.filterFocalLen = enaFocalLen->get_active ();
efs.filterISO = enaISO->get_active ();
efs.filterCamera = enaCamera->get_active ();
efs.filterLens = enaLens->get_active ();
std::vector<int> sel = camera->get_selected ();
for (int i=0; i<sel.size(); i++)
efs.cameras.insert (camera->get_text (sel[i]));
sel = lens->get_selected ();
for (int i=0; i<sel.size(); i++)
efs.lenses.insert (lens->get_text (sel[i]));
return efs;
}
void FilterPanel::valueChanged () {
if (listener)
listener->exifFilterChanged ();
}

71
rtgui/filterpanel.h Executable file
View File

@@ -0,0 +1,71 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _FILTERPANEL_
#define _FILTERPANEL_
#include <gtkmm.h>
#include <exiffiltersettings.h>
class FilterPanelListener {
public:
virtual void exifFilterChanged () {}
};
class FilterPanel : public Gtk::VBox {
protected:
Gtk::ListViewText* camera;
Gtk::ListViewText* lens;
Gtk::Entry* fnumberFrom;
Gtk::Entry* fnumberTo;
Gtk::Entry* shutterFrom;
Gtk::Entry* shutterTo;
Gtk::Entry* focalFrom;
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* enaCamera;
Gtk::CheckButton* enaLens;
int conns;
sigc::connection sChange[20];
ExifFilterSettings curefs;
FilterPanelListener* listener;
public:
FilterPanel ();
void setFilterPanelListener (FilterPanelListener* l) { listener = l; }
void setFilter (ExifFilterSettings& defefs);
ExifFilterSettings getFilter ();
bool isEnabled ();
void valueChanged ();
};
#endif

196
rtgui/guiutils.cc Executable file
View File

@@ -0,0 +1,196 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <guiutils.h>
#include <options.h>
#include <utils.h>
bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference) {
Glib::ListHandle<Gtk::Widget*> list = cont->get_children ();
Glib::ListHandle<Gtk::Widget*>::iterator i = list.begin ();
for (; i!=list.end() && *i!=w; i++);
if (i!=list.end()) {
if (increference)
w->reference ();
cont->remove (*w);
return true;
}
else
return false;
}
void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) {
if (options.thumbInterp==0)
rtengine::nearestInterp (src, sw, sh, dst, dw, dh);
else if (options.thumbInterp==1)
rtengine::bilinearInterp (src, sw, sh, dst, dw, dh);
}
Glib::ustring removeExtension (const Glib::ustring& filename) {
Glib::ustring bname = Glib::path_get_basename(filename);
int lastdot = bname.find_last_of ('.');
if (lastdot!=bname.npos)
return filename.substr (0, filename.size()-(bname.size()-lastdot));
else
return filename;
}
Glib::ustring getExtension (const Glib::ustring& filename) {
Glib::ustring bname = Glib::path_get_basename(filename);
int lastdot = bname.find_last_of ('.');
if (lastdot!=bname.npos)
return filename.substr (filename.size()-(bname.size()-lastdot)+1, filename.npos);
else
return "";
}
void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams) {
cr->set_line_width (1.0);
cr->rectangle (imx+0.5, imy+0.5, imw, imh);
cr->clip ();
double c1x = (cparams.x-startx)*scale;
double c1y = (cparams.y-starty)*scale;
double c2x = (cparams.x+cparams.w-1-startx)*scale;
double c2y = (cparams.y+cparams.h-1-starty)*scale;
cr->set_source_rgba (0, 0, 0, 2.0/3.0);
cr->rectangle (imx+0.5, imy+0.5, imw, c1y);
cr->rectangle (imx+0.5, imy+0.5+c2y, imw, imh-c2y);
cr->rectangle (imx+0.5, imy+0.5+c1y, c1x, c2y-c1y+1);
cr->rectangle (imx+0.5+c2x, imy+0.5+c1y, imw-c2x, c2y-c1y+1);
cr->fill ();
// rectangle around the cropped area and guides
if (cparams.guide!="None") {
double rectx1 = c1x + imx + 0.5;
double recty1 = c1y + imy + 0.5;
double rectx2 = c2x + imx + 0.5;
double recty2 = c2y + imy + 0.5;
cr->set_line_width (1.0);
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to (rectx1, recty1);
cr->line_to (rectx2, recty1);
cr->line_to (rectx2, recty2);
cr->line_to (rectx1, recty2);
cr->line_to (rectx1, recty1);
cr->stroke ();
cr->set_source_rgb (0.0, 0.0, 0.0);
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (rectx1, recty1);
cr->line_to (rectx2, recty1);
cr->line_to (rectx2, recty2);
cr->line_to (rectx1, recty2);
cr->line_to (rectx1, recty1);
cr->stroke ();
ds.resize (0);
cr->set_dash (ds, 0);
if (cparams.guide!="Rule of diagonals") {
// draw guide lines
std::vector<double> horiz_ratios;
std::vector<double> vert_ratios;
if (cparams.guide=="Rule of thirds") {
horiz_ratios.push_back (1.0/3.0);
horiz_ratios.push_back (2.0/3.0);
vert_ratios.push_back (1.0/3.0);
vert_ratios.push_back (2.0/3.0);
}
else if (cparams.guide=="Harmonic means 1") {
horiz_ratios.push_back (1.0-0.618);
vert_ratios.push_back (1.0-0.618);
}
else if (cparams.guide=="Harmonic means 2") {
horiz_ratios.push_back (0.618);
vert_ratios.push_back (1.0-0.618);
}
else if (cparams.guide=="Harmonic means 3") {
horiz_ratios.push_back (1.0-0.618);
vert_ratios.push_back (0.618);
}
else if (cparams.guide=="Harmonic means 4") {
horiz_ratios.push_back (0.618);
vert_ratios.push_back (0.618);
}
for (int i=0; i<vert_ratios.size(); i++) {
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1);
cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2);
cr->move_to (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]);
cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]);
cr->stroke ();
cr->set_source_rgb (0.0, 0.0, 0.0);
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1);
cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2);
cr->move_to (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]);
cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]);
cr->stroke ();
ds.resize (0);
cr->set_dash (ds, 0);
}
}
else {
int corners_from[4][2];
int corners_to[4][2];
int mindim = MIN (rectx2-rectx1+1, recty2-recty1+1);
corners_from[0][0] = rectx1;
corners_from[0][1] = recty1;
corners_to[0][0] = rectx1 + mindim;
corners_to[0][1] = recty1 + mindim;
corners_from[1][0] = rectx1;
corners_from[1][1] = recty2;
corners_to[1][0] = rectx1 + mindim;
corners_to[1][1] = recty2 - mindim;
corners_from[2][0] = rectx2;
corners_from[2][1] = recty1;
corners_to[2][0] = rectx2 - mindim;
corners_to[2][1] = recty1 + mindim;
corners_from[3][0] = rectx2;
corners_from[3][1] = recty2;
corners_to[3][0] = rectx2 - mindim;
corners_to[3][1] = recty2 - mindim;
for (int i=0; i<4; i++) {
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to (corners_from[i][0], corners_from[i][1]);
cr->line_to (corners_to[i][0], corners_to[i][1]);
cr->stroke ();
cr->set_source_rgb (0.0, 0.0, 0.0);
std::valarray<double> ds (1);
ds[0] = 4;
cr->set_dash (ds, 0);
cr->move_to (corners_from[i][0], corners_from[i][1]);
cr->line_to (corners_to[i][0], corners_to[i][1]);
cr->stroke ();
ds.resize (0);
cr->set_dash (ds, 0);
}
}
}
cr->reset_clip ();
}

31
rtgui/guiutils.h Executable file
View File

@@ -0,0 +1,31 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __UTILS_
#define __UTILS_
#include <gtkmm.h>
#include <rtengine.h>
bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference=true);
void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh);
Glib::ustring removeExtension (const Glib::ustring& filename);
Glib::ustring getExtension (const Glib::ustring& filename);
void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams);
#endif

464
rtgui/histogrampanel.cc Executable file
View File

@@ -0,0 +1,464 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <histogrampanel.h>
#include <multilangmgr.h>
HistogramPanel::HistogramPanel () {
histogramArea = Gtk::manage (new HistogramArea ());
showRed = Gtk::manage (new Gtk::ToggleButton ("R"));
showGreen = Gtk::manage (new Gtk::ToggleButton ("G"));
showBlue = Gtk::manage (new Gtk::ToggleButton ("B"));
showValue = Gtk::manage (new Gtk::ToggleButton ("L"));
Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox (false, 0));
showRed->set_active (true);
showGreen->set_active (true);
showBlue->set_active (true);
showValue->set_active (true);
vbox->pack_start (*showRed, Gtk::PACK_SHRINK, 2);
vbox->pack_start (*showGreen, Gtk::PACK_SHRINK, 2);
vbox->pack_start (*showBlue, Gtk::PACK_SHRINK, 2);
vbox->pack_start (*showValue, Gtk::PACK_SHRINK, 2);
pack_start (*histogramArea);
pack_end (*vbox, Gtk::PACK_SHRINK, 2);
showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
showGreen->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
showBlue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
showValue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) );
show_all ();
showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R"));
showGreen->set_tooltip_text (M("HISTOGRAM_TOOLTIP_G"));
showBlue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_B"));
showValue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_L"));
rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) );
}
void HistogramPanel::resized (Gtk::Allocation& req) {
rconn.block (true);
if (req.get_width()/2>150)
set_size_request (req.get_width(), 150);
else
set_size_request (req.get_width(), req.get_width()/2);
rconn.block (false);
histogramArea->renderHistogram ();
histogramArea->queue_draw ();
}
void HistogramPanel::rgbv_toggled () {
histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active());
histogramArea->queue_draw ();
}
HistogramArea::HistogramArea () :
needVal(true), needRed(true), needGreen(true), needBlue(true), oldwidth(-1), valid(false), showFull(true) {
haih = new HistogramAreaIdleHelper;
haih->harea = this;
haih->destroyed = false;
haih->pending = 0;
signal_style_changed().connect( sigc::mem_fun(*this, &HistogramArea::styleChanged) );
}
HistogramArea::~HistogramArea () {
if (haih->pending)
haih->destroyed = true;
else
delete haih;
}
void HistogramArea::updateOptions (bool r, bool g, bool b, bool v) {
needRed = r;
needGreen = g;
needBlue = b;
needVal = v;
renderHistogram ();
}
int histupdate (void* data) {
gdk_threads_enter ();
HistogramAreaIdleHelper* haih = (HistogramAreaIdleHelper*)data;
if (haih->destroyed) {
if (haih->pending == 1)
delete haih;
else
haih->pending--;
gdk_threads_leave ();
return 0;
}
haih->harea->renderHistogram ();
haih->harea->queue_draw ();
haih->pending--;
gdk_threads_leave ();
return 0;
}
void HistogramArea::update (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh) {
if (rh!=NULL) {
memcpy (lhist, lh, 256*sizeof(unsigned int));
memcpy (rhist, rh, 256*sizeof(unsigned int));
memcpy (ghist, gh, 256*sizeof(unsigned int));
memcpy (bhist, bh, 256*sizeof(unsigned int));
valid = true;
}
else
valid = false;
haih->pending++;
g_idle_add (histupdate, haih);
}
void HistogramArea::renderHistogram () {
if (!is_realized ())
return;
Glib::RefPtr<Gdk::Window> window = get_window();
int winx, winy, winw, winh, wind;
window->get_geometry(winx, winy, winw, winh, wind);
backBuffer = Gdk::Pixmap::create (window, winw, winh, -1);
Glib::RefPtr<Gdk::GC> bgc = Gdk::GC::create(backBuffer);
bgc->set_foreground (white);
backBuffer->draw_rectangle (bgc, true, 0, 0, winw, winh);
if (valid) {
// compute height of the full histogram (realheight) and
int fullhistheight = 0;
for (int i=0; i<256; i++) {
if (needVal && lhist[i]>fullhistheight)
fullhistheight = lhist[i];
if (needRed && rhist[i]>fullhistheight)
fullhistheight = rhist[i];
if (needGreen && ghist[i]>fullhistheight)
fullhistheight = ghist[i];
if (needBlue && bhist[i]>fullhistheight)
fullhistheight = bhist[i];
}
// compute two hights, one for the magnified view and one for the threshold
int realhistheight = fullhistheight;
if (!showFull) {
int area1thres = 0;
int area2thres = 0;
int area = 0;
for (int i=0; i<fullhistheight; i++) {
for (int j=0; j<256; j++)
if ((needVal && lhist[j]>i) || (needRed && rhist[j]>i) || (needGreen && ghist[j]>i) || (needBlue && bhist[j]>i))
area++;
if (area1thres==0 && (double)area / (256*(i+1)) < 0.3)
area1thres = i;
if (area2thres==0 && (double)area / (256*(i+1)) < 0.3)
area2thres = i;
if (area1thres && area2thres)
break;
}
if (area1thres>0 && area2thres>0 && area1thres<fullhistheight)
realhistheight = area2thres;
}
if (realhistheight<winh-2)
realhistheight = winh-2;
Cairo::RefPtr<Cairo::Context> cr = backBuffer->create_cairo_context();
cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
cr->set_line_width (1.0);
double stepSize = (winw-1) / 256.0;
if (needVal) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.75, 0.75, 0.75);
for (int i=0; i<256; i++) {
double val = lhist[i] * (double)(winh-2) / realhistheight;
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i*stepSize, winh-1-val);
}
cr->save ();
cr->line_to (winw-1, winh-1);
cr->fill_preserve ();
cr->restore ();
cr->set_source_rgb (0.5, 0.5, 0.5);
cr->stroke ();
}
if (needRed) {
cr->move_to (0, winh-1);
cr->set_source_rgb (1.0, 0.0, 0.0);
for (int i=0; i<256; i++) {
double val = rhist[i] * (double)(winh-2) / realhistheight;
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i*stepSize, winh-1-val);
}
cr->stroke ();
}
if (needGreen) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.0, 1.0, 0.0);
for (int i=0; i<256; i++) {
double val = ghist[i] * (double)(winh-2) / realhistheight;
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i*stepSize, winh-1-val);
}
cr->stroke ();
}
if (needBlue) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.0, 0.0, 1.0);
for (int i=0; i<256; i++) {
int val = bhist[i] * (double)(winh-2) / realhistheight;
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i*stepSize, winh-1-val);
}
cr->stroke ();
}
}
/*
// scale histogram to width winw-1
int* vval = new int[winw-1];
int* vred = new int[winw-1];
int* vgreen = new int[winw-1];
int* vblue = new int[winw-1];
memset (vval, 0, sizeof(int)*(winw-1));
memset (vred, 0, sizeof(int)*(winw-1));
memset (vgreen, 0, sizeof(int)*(winw-1));
memset (vblue, 0, sizeof(int)*(winw-1));
int index = 0;
double scale = 256.0 / (winw-2);
for (int i=0; i<=winw-2; i++) {
int samples = 0;
while (index < 256 && (int)(index/scale) == i) {
vval[i] += lhist[index];
vred[i] += rhist[index];
vgreen[i] += ghist[index];
vblue[i] += bhist[index];
index++;
samples++;
}
if (samples>0) {
vval[i] /= samples;
vred[i] /= samples;
vgreen[i] /= samples;
vblue[i] /= samples;
}
}
// compute height of the full histogram (realheight) and
int fullhistheight = 0;
for (int i=0; i<=winw-2; i++) {
if (needVal && vval[i]>fullhistheight)
fullhistheight = vval[i];
if (needRed && vred[i]>fullhistheight)
fullhistheight = vred[i];
if (needGreen && vgreen[i]>fullhistheight)
fullhistheight = vgreen[i];
if (needBlue && vblue[i]>fullhistheight)
fullhistheight = vblue[i];
}
// compute two hights, one for the magnified view and one for the threshold
int realhistheight = fullhistheight;
if (!showFull) {
int area1thres = 0;
int area2thres = 0;
int area = 0;
for (int i=0; i<fullhistheight; i++) {
for (int j=0; j<winw-1; j++)
if ((needVal && vval[j]>i) || (needRed && vred[j]>i) || (needGreen && vgreen[j]>i) || (needBlue && vblue[j]>i))
area++;
if (area1thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3)
area1thres = i;
if (area2thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3)
area2thres = i;
if (area1thres && area2thres)
break;
}
if (area1thres>0 && area2thres>0 && area1thres<fullhistheight)
realhistheight = area2thres;
}
if (realhistheight<winh-2)
realhistheight = winh-2;
Cairo::RefPtr<Cairo::Context> cr = backBuffer->create_cairo_context();
cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
cr->set_line_width (1.0);
if (needVal) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.75, 0.75, 0.75);
for (int i=0; i<=winw-2; i++) {
int val = (int)(vval[i] * (double)(winh-2) / realhistheight);
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i+1, winh-1-val);
}
cr->fill_preserve ();
cr->set_source_rgb (0.5, 0.5, 0.5);
cr->stroke ();
}
if (needRed) {
cr->move_to (0, winh-1);
cr->set_source_rgb (1.0, 0.0, 0.0);
for (int i=0; i<=winw-2; i++) {
int val = (int)(vred[i] * (double)(winh-2) / realhistheight);
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i+1, winh-1-val);
}
cr->stroke ();
}
if (needGreen) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.0, 1.0, 0.0);
for (int i=0; i<=winw-2; i++) {
int val = (int)(vgreen[i] * (double)(winh-2) / realhistheight);
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i+1, winh-1-val);
}
cr->stroke ();
}
if (needBlue) {
cr->move_to (0, winh-1);
cr->set_source_rgb (0.0, 0.0, 1.0);
for (int i=0; i<=winw-2; i++) {
int val = (int)(vblue[i] * (double)(winh-2) / realhistheight);
if (val>winh-1)
val = winh-1;
if (i>0)
cr->line_to (i+1, winh-1-val);
}
cr->stroke ();
}
delete [] vval;
delete [] vred;
delete [] vgreen;
delete [] vblue;
}
*/
bgc->set_foreground (mgray);
backBuffer->draw_rectangle (bgc, false, 0, 0, winw-1, winh-1);
bgc->set_line_attributes (1, Gdk::LINE_ON_OFF_DASH, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
backBuffer->draw_line (bgc, winw/3, 0, winw/3, winh-1);
backBuffer->draw_line (bgc, 2*winw/3, 0, 2*winw/3, winh-1);
backBuffer->draw_line (bgc, 0, winh/3, winw-1, winh/3);
backBuffer->draw_line (bgc, 0, 2*winh/3, winw-1, 2*winh/3);
bgc->set_line_attributes (1, Gdk::LINE_SOLID, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
oldwidth = winw;
oldheight = winh;
}
void HistogramArea::on_realize () {
Gtk::DrawingArea::on_realize();
Glib::RefPtr<Gdk::Window> window = get_window();
gc_ = Gdk::GC::create(window);
add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK);
Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
black = Gdk::Color ("black");
red = Gdk::Color ("red");
green = Gdk::Color ("green");
blue = Gdk::Color ("blue");
lgray = Gdk::Color ("gray75");
mgray = Gdk::Color ("gray50");
dgray = Gdk::Color ("gray25");
colormap->alloc_color(black);
colormap->alloc_color(white);
colormap->alloc_color(red);
colormap->alloc_color(green);
colormap->alloc_color(blue);
colormap->alloc_color(lgray);
colormap->alloc_color(mgray);
colormap->alloc_color(dgray);
}
void HistogramArea::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
white = get_style()->get_base(Gtk::STATE_NORMAL);
queue_draw ();
}
bool HistogramArea::on_expose_event(GdkEventExpose* event) {
Glib::RefPtr<Gdk::Window> window = get_window();
int winx, winy, winw, winh, wind;
window->get_geometry(winx, winy, winw, winh, wind);
if (winw!=oldwidth && winh!=oldheight)
renderHistogram ();
window->draw_drawable (gc_, backBuffer, 0, 0, 0, 0, -1, -1);
return true;
}
bool HistogramArea::on_button_press_event (GdkEventButton* event) {
if (event->type==GDK_2BUTTON_PRESS && event->button==1) {
showFull = !showFull;
renderHistogram ();
queue_draw ();
}
}

98
rtgui/histogrampanel.h Executable file
View File

@@ -0,0 +1,98 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _HISTOGRAMPANEL_
#define _HISTOGRAMPANEL_
#include <gtkmm.h>
#include <glibmm.h>
#include <rtengine.h>
class HistogramArea;
struct HistogramAreaIdleHelper {
HistogramArea* harea;
bool destroyed;
int pending;
};
class HistogramArea : public Gtk::DrawingArea {
protected:
Glib::RefPtr<Gdk::GC> gc_;
Glib::RefPtr<Gdk::Pixmap> backBuffer;
Gdk::Color black;
Gdk::Color white;
Gdk::Color red;
Gdk::Color green;
Gdk::Color blue;
Gdk::Color lgray;
Gdk::Color mgray;
Gdk::Color dgray;
unsigned int lhist[256];
unsigned int rhist[256];
unsigned int ghist[256];
unsigned int bhist[256];
bool valid;
bool showFull;
int oldwidth, oldheight;
bool needVal;
bool needRed;
bool needGreen;
bool needBlue;
HistogramAreaIdleHelper* haih;
public:
HistogramArea();
~HistogramArea();
void renderHistogram ();
void update (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh);
void updateOptions (bool r, bool g, bool b, bool v);
void on_realize();
bool on_expose_event(GdkEventExpose* event);
bool on_button_press_event (GdkEventButton* event);
void styleChanged (const Glib::RefPtr<Gtk::Style>& style);
};
class HistogramPanel : public Gtk::HBox, public rtengine::HistogramListener {
protected:
HistogramArea* histogramArea;
Gtk::ToggleButton* showRed;
Gtk::ToggleButton* showGreen;
Gtk::ToggleButton* showBlue;
Gtk::ToggleButton* showValue;
sigc::connection rconn;
public:
HistogramPanel ();
void histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh) { histogramArea->update (rh, gh, bh, lh); }
void rgbv_toggled ();
void resized (Gtk::Allocation& req);
};
#endif

326
rtgui/history.cc Executable file
View File

@@ -0,0 +1,326 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <history.h>
#include <multilangmgr.h>
using namespace rtengine;
using namespace rtengine::procparams;
Glib::ustring eventDescrArray[NUMOFEVENTS];
extern Glib::ustring argv0;
History::History (bool bookmarkSupport) : tpc (NULL), bmnum (1), blistener(NULL) {
// fill history event message array
for (int i=0; i<NUMOFEVENTS; i++)
eventDescrArray[i] = M(Glib::ustring::compose("HISTORY_MSG_%1", i+1));
// History List
// ~~~~~~~~~~~~
hscrollw = Gtk::manage (new Gtk::ScrolledWindow ());
hscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
Gtk::Frame* histFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_LABEL")));
histFrame->add (*hscrollw);
pack_start (*histFrame);
hTreeView = Gtk::manage (new Gtk::TreeView ());
hscrollw->add (*hTreeView);
historyModel = Gtk::ListStore::create (historyColumns);
hTreeView->set_model (historyModel);
// hTreeView->set_headers_visible (false);
Gtk::CellRendererText *changecrt = Gtk::manage (new Gtk::CellRendererText());
Gtk::CellRendererText *valuecrt = Gtk::manage (new Gtk::CellRendererText());
Gtk::TreeView::Column *hviewcol = Gtk::manage (new Gtk::TreeView::Column (""));
hviewcol->pack_start (*changecrt, true);
hviewcol->add_attribute (changecrt->property_markup (), historyColumns.text);
hviewcol->set_resizable (true);
Gtk::TreeView::Column *hviewcol2 = Gtk::manage (new Gtk::TreeView::Column (""));
hviewcol2->pack_start (*valuecrt, true);
hviewcol2->add_attribute (valuecrt->property_markup (), historyColumns.value);
valuecrt->set_property ("xalign", 1.0);
hTreeView->append_column (*hviewcol);
hTreeView->append_column (*hviewcol2);
hviewcol2->set_sizing (Gtk::TREE_VIEW_COLUMN_FIXED);
selchangehist = hTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::historySelectionChanged));
// Bookmark List
// ~~~~~~~~~~~~~
Gtk::HSeparator* hsepb = Gtk::manage (new Gtk::HSeparator ());
pack_end (*hsepb, Gtk::PACK_SHRINK, 0);
Gtk::HBox* ahbox = Gtk::manage (new Gtk::HBox ());
addBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_NEWSNAPSHOT")));
Gtk::Image* addimg = Gtk::manage (new Gtk::Image (argv0+"/images/list-add.png"));
addBookmark->set_image (*addimg);
ahbox->pack_start (*addBookmark);
delBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_DELSNAPSHOT")));
Gtk::Image* delimg = Gtk::manage (new Gtk::Image (argv0+"/images/list-remove.png"));
delBookmark->set_image (*delimg);
ahbox->pack_start (*delBookmark);
bscrollw = Gtk::manage (new Gtk::ScrolledWindow ());
// bscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
bscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
bscrollw->set_size_request (-1, 75);
Gtk::Frame* bmFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_SNAPSHOTS")));
Gtk::VBox* bmBox = Gtk::manage (new Gtk::VBox ());
bmFrame->add (*bmBox);
bmBox->pack_start (*bscrollw, Gtk::PACK_SHRINK, 4);
bmBox->pack_end (*ahbox, Gtk::PACK_SHRINK, 4);
if (bookmarkSupport)
pack_end (*bmFrame, Gtk::PACK_SHRINK, 4);
bTreeView = Gtk::manage (new Gtk::TreeView ());
bscrollw->add (*bTreeView);
bookmarkModel = Gtk::ListStore::create (bookmarkColumns);
bTreeView->set_model (bookmarkModel);
bTreeView->set_headers_visible (false);
bTreeView->append_column_editable (M("HISTORY_SNAPSHOTS"), bookmarkColumns.text);
selchangebm = bTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::bookmarkSelectionChanged));
addBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::addBookmarkPressed) );
delBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::delBookmarkPressed) );
// hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL);
hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_BOTH);
hTreeView->signal_size_allocate().connect( sigc::mem_fun(*this, &History::resized) );
hTreeView->set_enable_search(false);
bTreeView->set_enable_search(false);
show_all_children ();
}
void History::initHistory () {
historyModel->clear ();
bookmarkModel->clear ();
}
void History::clearParamChanges () {
initHistory ();
}
void History::historySelectionChanged () {
Glib::RefPtr<Gtk::TreeSelection> selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
if (row)
bTreeView->get_selection()->unselect_all ();
if (row && tpc) {
ProcParams params = row[historyColumns.params];
ParamsEdited paramsEdited = row[historyColumns.paramsEdited];
tpc->profileChange (&params, EvHistoryBrowsed, row[historyColumns.text], &paramsEdited);
}
if (blistener) {
Gtk::TreeModel::Path path = historyModel->get_path (iter);
path.prev ();
iter = historyModel->get_iter (path);
if (blistener && iter)
blistener->historyBeforeLineChanged (iter->get_value (historyColumns.params));
}
}
}
void History::bookmarkSelectionChanged () {
Glib::RefPtr<Gtk::TreeSelection> selection = bTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
if (row)
hTreeView->get_selection()->unselect_all ();
if (row && tpc) {
ProcParams params = row[bookmarkColumns.params];
ParamsEdited paramsEdited = row[bookmarkColumns.paramsEdited];
tpc->profileChange (&params, EvBookmarkSelected, row[bookmarkColumns.text], &paramsEdited);
}
}
}
void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) {
// to prevent recursion, we filter out the events triggered by the history
if (ev==EvHistoryBrowsed)
return;
selchangehist.block (true);
if (ev==EvPhotoLoaded)
initHistory ();
// construct formatted list content
Glib::ustring text = Glib::ustring::compose ("<b>%1</b>", eventDescrArray[ev]);
Glib::RefPtr<Gtk::TreeSelection> selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
// remove all rows after the selection
if (iter) {
iter++;
while (iter)
iter = historyModel->erase (iter);
}
// lookup the last remaining item in the list
int size = historyModel->children().size ();
Gtk::TreeModel::Row row;
if (size>0)
row = historyModel->children()[size-1];
// if there is no last item or its chev!=ev, create a new one
if (size==0 || !row || row[historyColumns.chev]!=ev) {
Gtk::TreeModel::Row newrow = *(historyModel->append());
newrow[historyColumns.realText] = eventDescrArray[ev];
newrow[historyColumns.text] = text;
newrow[historyColumns.value] = descr;
newrow[historyColumns.chev] = ev;
newrow[historyColumns.params] = *params;
newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (ev!=EvBookmarkSelected)
selection->select (newrow);
if (blistener && row)
blistener->historyBeforeLineChanged (row[historyColumns.params]);
else if (blistener && size==0)
blistener->historyBeforeLineChanged (newrow[historyColumns.params]);
}
// else just update it
else {
row[historyColumns.realText] = eventDescrArray[ev];
row[historyColumns.text] = text;
row[historyColumns.value] = descr;
row[historyColumns.chev] = ev;
row[historyColumns.params] = *params;
row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (ev!=EvBookmarkSelected)
selection->select (row);
}
if (ev!=EvBookmarkSelected)
bTreeView->get_selection()->unselect_all ();
if (!selection->get_selected_rows().empty()) {
Gtk::TreeView::Selection::ListHandle_Path selp = selection->get_selected_rows();
hTreeView->scroll_to_row (*selp.begin());
}
selchangehist.block (false);
}
void History::addBookmarkWithText (Glib::ustring text) {
// lookup the selected item in the history
Glib::RefPtr<Gtk::TreeSelection> selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
Gtk::TreeModel::Row row = *iter;
if (!row) {
return;
}
// append new row to bookmarks
Gtk::TreeModel::Row newrow = *(bookmarkModel->append());
newrow[bookmarkColumns.text] = text;
ProcParams params = row[historyColumns.params];
newrow[bookmarkColumns.params] = params;
ParamsEdited paramsEdited = row[historyColumns.paramsEdited];
newrow[bookmarkColumns.paramsEdited] = paramsEdited;
}
void History::addBookmarkPressed () {
if (hTreeView->get_selection()->get_selected())
addBookmarkWithText (Glib::ustring::compose ("%1 %2", M("HISTORY_SNAPSHOT"), bmnum++));
}
void History::delBookmarkPressed () {
// lookup the selected item in the bookmark
Glib::RefPtr<Gtk::TreeSelection> selection = bTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (!iter) {
return;
}
// remove selected bookmark
bookmarkModel->erase (iter);
// select last item in history
int size = historyModel->children().size ();
Gtk::TreeModel::Row row = historyModel->children()[size-1];
hTreeView->get_selection()->select (row);
}
void History::undo () {
Glib::RefPtr<Gtk::TreeSelection> selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter && iter!=historyModel->children().begin())
selection->select (--iter);
else if (!iter) {
int size = historyModel->children().size ();
if (size>1)
selection->select (historyModel->children()[size-2]);
}
}
void History::redo () {
Glib::RefPtr<Gtk::TreeSelection> selection = hTreeView->get_selection();
Gtk::TreeModel::iterator iter = selection->get_selected();
if (iter) {
iter++;
if (iter!=historyModel->children().end())
selection->select (iter);
}
else {
int size = historyModel->children().size ();
if (size>1)
selection->select (historyModel->children()[size-2]);
}
}
void History::resized (Gtk::Allocation& req) {
}
bool History::getBeforeLineParams (rtengine::procparams::ProcParams& params) {
int size = historyModel->children().size ();
if (size==0 || !blistener)
return false;
Gtk::TreeModel::Row row;
row = historyModel->children()[size==1 ? 0 : size-2];
params = row[historyColumns.params];
return true;
}

105
rtgui/history.h Executable file
View File

@@ -0,0 +1,105 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _HISTORY_
#define _HISTORY_
#include <gtkmm.h>
#include <rtengine.h>
#include <pparamschangelistener.h>
#include <profilechangelistener.h>
#include <paramsedited.h>
class HistoryBeforeLineListener {
public:
virtual void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {}
};
class History : public Gtk::VBox, public PParamsChangeListener {
public:
class HistoryColumns : public Gtk::TreeModel::ColumnRecord {
public:
Gtk::TreeModelColumn<Glib::ustring> realText;
Gtk::TreeModelColumn<Glib::ustring> text;
Gtk::TreeModelColumn<Glib::ustring> value;
Gtk::TreeModelColumn<rtengine::procparams::ProcParams> params;
Gtk::TreeModelColumn<rtengine::ProcEvent> chev;
Gtk::TreeModelColumn<ParamsEdited> paramsEdited;
HistoryColumns() { add(text); add(realText); add(value); add(chev); add(params); add(paramsEdited); }
};
HistoryColumns historyColumns;
class BookmarkColumns : public Gtk::TreeModel::ColumnRecord {
public:
Gtk::TreeModelColumn<Glib::ustring> text;
Gtk::TreeModelColumn<rtengine::procparams::ProcParams> params;
Gtk::TreeModelColumn<ParamsEdited> paramsEdited;
BookmarkColumns() { add(text); add(params); add(paramsEdited); }
};
BookmarkColumns bookmarkColumns;
protected:
Gtk::ScrolledWindow* hscrollw;
Gtk::TreeView* hTreeView;
Glib::RefPtr<Gtk::ListStore> historyModel;
Gtk::ScrolledWindow* bscrollw;
Gtk::TreeView* bTreeView;
Glib::RefPtr<Gtk::ListStore> bookmarkModel;
Gtk::Button* addBookmark;
Gtk::Button* delBookmark;
sigc::connection selchangehist;
sigc::connection selchangebm;
HistoryBeforeLineListener * blistener;
ProfileChangeListener* tpc;
ParamsEdited defParamsEdited;
int bmnum;
public:
History (bool bookmarkSupport = true);
void setProfileChangeListener (ProfileChangeListener* tpc_) { tpc = tpc_; }
void setHistoryBeforeLineListener (HistoryBeforeLineListener* bll) { blistener = bll; }
// pparamschangelistener interface
void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL);
void clearParamChanges ();
void historySelectionChanged ();
void bookmarkSelectionChanged ();
void initHistory ();
bool getBeforeLineParams (rtengine::procparams::ProcParams& params);
void addBookmarkWithText (Glib::ustring text);
void addBookmarkPressed ();
void delBookmarkPressed ();
void resized (Gtk::Allocation& req);
void undo ();
void redo ();
};
#endif

131
rtgui/hlrec.cc Executable file
View File

@@ -0,0 +1,131 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <hlrec.h>
#include <sstream>
using namespace rtengine;
using namespace rtengine::procparams;
HLRecovery::HLRecovery () : ToolPanel() {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLE")));
enabled->set_active (false);
pack_start (*enabled);
method = Gtk::manage (new Gtk::ComboBoxText ());
method->append_text (M("TP_HLREC_LUMINANCE"));
method->append_text (M("TP_HLREC_CIELAB"));
method->append_text (M("TP_HLREC_COLOR"));
method->set_active (0);
Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_HLREC_METHOD")));
hb->pack_start (*lab, Gtk::PACK_SHRINK, 4);
hb->pack_start (*method);
pack_start (*hb);
enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &HLRecovery::enabledChanged) );
methconn = method->signal_changed().connect ( sigc::mem_fun(*this, &HLRecovery::methodChanged) );
show_all ();
}
void HLRecovery::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited)
enabled->set_inconsistent (!pedited->hlrecovery.enabled);
enaconn.block (true);
enabled->set_active (pp->hlrecovery.enabled);
enaconn.block (false);
if (pedited && !pedited->hlrecovery.method)
method->set_active (3);
else if (pp->hlrecovery.method=="Luminance")
method->set_active (0);
else if (pp->hlrecovery.method=="CIELab blending")
method->set_active (1);
else if (pp->hlrecovery.method=="Color")
method->set_active (2);
lastEnabled = pp->hlrecovery.enabled;
enableListener ();
}
void HLRecovery::write (ProcParams* pp, ParamsEdited* pedited) {
if (pedited) {
pedited->hlrecovery.method = method->get_active_row_number()!=3;
pedited->hlrecovery.enabled = !enabled->get_inconsistent();
}
pp->hlrecovery.enabled = enabled->get_active();
if (method->get_active_row_number()==0)
pp->hlrecovery.method = "Luminance";
else if (method->get_active_row_number()==1)
pp->hlrecovery.method = "CIELab blending";
else if (method->get_active_row_number()==2)
pp->hlrecovery.method = "Color";
}
void HLRecovery::enabledChanged () {
if (batchMode) {
if (enabled->get_inconsistent()) {
enabled->set_inconsistent (false);
enaconn.block (true);
enabled->set_active (false);
enaconn.block (false);
}
else if (lastEnabled)
enabled->set_inconsistent (true);
lastEnabled = enabled->get_active ();
}
if (listener) {
if (enabled->get_active ())
listener->panelChanged (EvHREnabled, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvHREnabled, M("GENERAL_DISABLED"));
}
}
void HLRecovery::methodChanged () {
if (listener) {
if (enabled->get_active ())
listener->panelChanged (EvHRMethod, method->get_active_text ());
}
}
void HLRecovery::setRaw (bool raw) {
disableListener ();
set_sensitive (raw);
enableListener ();
}
void HLRecovery::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
method->append_text ("(Unchanged)");
}

48
rtgui/hlrec.h Executable file
View File

@@ -0,0 +1,48 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _HLREC_H_
#define _HLREC_H_
#include <gtkmm.h>
#include <toolpanel.h>
class HLRecovery : public Gtk::VBox, public ToolPanel {
protected:
Gtk::CheckButton* enabled;
Gtk::ComboBoxText* method;
sigc::connection methconn;
sigc::connection enaconn;
bool lastEnabled;
public:
HLRecovery ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void setRaw (bool raw);
void enabledChanged ();
void methodChanged ();
};
#endif

21
rtgui/iccfromwindows.txt Executable file
View File

@@ -0,0 +1,21 @@
+#elif defined G_OS_WIN32
+ if (config->display_profile_from_gdk)
+ {
+ HDC hdc = GetDC (NULL);
+
+ if (hdc)
+ {
+ gchar *path;
+ gint32 len = 0;
+
+ GetICMProfile (hdc, &len, NULL);
+ path = g_new (gchar, len);
+
+ if (GetICMProfile (hdc, &len, path))
+ profile = cmsOpenProfileFromFile (path, "r");
+
+ g_free (path);
+ ReleaseDC (NULL, hdc);
+ }
+ }
#endif

290
rtgui/icmpanel.cc Executable file
View File

@@ -0,0 +1,290 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <icmpanel.h>
#include <options.h>
#include <guiutils.h>
using namespace rtengine;
using namespace rtengine::procparams;
extern Options options;
ICMPanel::ICMPanel () : ToolPanel(), icmplistener(NULL), iunchanged(NULL) {
// set_border_width (4);
ipDialog = Gtk::manage (new Gtk::FileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN));
opDialog = Gtk::manage (new Gtk::FileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN));
Gtk::Label* ilab = Gtk::manage (new Gtk::Label ());
ilab->set_alignment (0.0, 0.5);
ilab->set_markup (Glib::ustring("<b>") + M("TP_ICM_INPUTPROFILE") + "</b>");
pack_start (*ilab, Gtk::PACK_SHRINK, 4);
iembedded = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTEMBEDDED")));
pack_start (*iembedded, Gtk::PACK_SHRINK, 4);
icamera = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERA")));
pack_start (*icamera, Gtk::PACK_SHRINK, 4);
ifromfile = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCUSTOM")+":"));
Gtk::HBox* ffbox = Gtk::manage (new Gtk::HBox ());
ffbox->pack_start (*ifromfile, Gtk::PACK_SHRINK);
ffbox->pack_start (*ipDialog);
pack_start (*ffbox, Gtk::PACK_SHRINK, 4);
opts = icamera->get_group();
iembedded->set_group (opts);
ifromfile->set_group (opts);
igamma = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_GAMMABEFOREINPUT")));
igamma->set_sensitive (false);
pack_start (*igamma, Gtk::PACK_SHRINK, 4);
saveRef = Gtk::manage (new Gtk::Button (M("TP_ICM_SAVEREFERENCE")));
saveRef->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)));
pack_start (*saveRef, Gtk::PACK_SHRINK, 4);
Gtk::HSeparator* hsep1 = Gtk::manage (new Gtk::HSeparator ());
pack_start (*hsep1, Gtk::PACK_SHRINK, 2);
Gtk::Label* wlab = Gtk::manage (new Gtk::Label ());
wlab->set_alignment (0.0, 0.5);
wlab->set_markup (Glib::ustring("<b>") + M("TP_ICM_WORKINGPROFILE") + "</b>");
pack_start (*wlab, Gtk::PACK_SHRINK, 4);
wnames = Gtk::manage (new Gtk::ComboBoxText ());
pack_start (*wnames, Gtk::PACK_SHRINK, 4);
Gtk::HSeparator* hsep2 = Gtk::manage (new Gtk::HSeparator ());
pack_start (*hsep2, Gtk::PACK_SHRINK, 2);
Gtk::Label* olab = Gtk::manage (new Gtk::Label ());
olab->set_alignment (0.0, 0.5);
olab->set_markup (Glib::ustring("<b>") + M("TP_ICM_OUTPUTPROFILE") + "</b>");
pack_start (*olab, Gtk::PACK_SHRINK, 4);
onames = Gtk::manage (new Gtk::ComboBoxText ());
pack_start (*onames, Gtk::PACK_SHRINK, 4);
std::vector<std::string> wpnames = rtengine::getWorkingProfiles ();
for (int i=0; i<wpnames.size(); i++)
wnames->append_text (wpnames[i]);
onames->append_text (M("TP_ICM_NOICM"));
onames->set_active (0);
std::vector<std::string> opnames = rtengine::getOutputProfiles ();
for (int i=0; i<opnames.size(); i++)
onames->append_text (opnames[i]);
wnames->set_active (0);
onames->set_active (0);
Gtk::FileFilter filter_icc;
filter_icc.set_name(M("TP_ICM_FILEDLGFILTERICM"));
filter_icc.add_pattern("*.icc");
filter_icc.add_pattern("*.icm");
filter_icc.add_pattern("*.ICC");
filter_icc.add_pattern("*.ICM");
Gtk::FileFilter filter_any;
filter_any.set_name(M("TP_ICM_FILEDLGFILTERANY"));
filter_any.add_pattern("*");
ipDialog->add_filter (filter_icc);
ipDialog->add_filter (filter_any);
opDialog->add_filter (filter_icc);
opDialog->add_filter (filter_any);
if (Glib::file_test (options.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) {
ipDialog->set_current_folder (options.rtSettings.iccDirectory);
opDialog->set_current_folder (options.rtSettings.iccDirectory);
}
oldip = "";
wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) );
onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) );
icamera->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
iembedded->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
ifromfile->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
ipc = ipDialog->signal_selection_changed().connect( sigc::mem_fun(*this, &ICMPanel::ipSelectionChanged) );
saveRef->signal_pressed().connect( sigc::mem_fun(*this, &ICMPanel::saveReferencePressed) );
show_all ();
}
void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
ipc.block (true);
if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()==Gtk::STATE_INSENSITIVE)) {
iembedded->set_active (true);
igamma->set_sensitive (false);
}
else if ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()!=Gtk::STATE_INSENSITIVE) {
icamera->set_active (true);
igamma->set_sensitive (false);
}
else {
ifromfile->set_active (true);
oldip = pp->icm.input.substr(5);
ipDialog->set_filename (pp->icm.input.substr(5));
igamma->set_sensitive (true);
}
wnames->set_active_text (pp->icm.working);
if (pp->icm.output=="No ICM: sRGB output")
onames->set_active_text (M("TP_ICM_NOICM"));
else
onames->set_active_text (pp->icm.output);
if (onames->get_active_row_number()==-1)
onames->set_active_text (M("TP_ICM_NOICM"));
igamma->set_active (pp->icm.gammaOnInput);
if (pedited) {
iunchanged->set_active (!pedited->icm.input);
igamma->set_sensitive (false);
if (!pedited->icm.working)
wnames->set_active_text("(Unchanged)");
if (!pedited->icm.output)
onames->set_active_text("(Unchanged)");
}
ipc.block (false);
enableListener ();
}
void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) {
if (iembedded->get_active ())
pp->icm.input = "(embedded)";
else if (icamera->get_active ())
pp->icm.input = "(camera)";
else
pp->icm.input = "file:"+ipDialog->get_filename ();
pp->icm.working = wnames->get_active_text ();
if (onames->get_active_text()==M("TP_ICM_NOICM"))
pp->icm.output = "No ICM: sRGB output";
else
pp->icm.output = onames->get_active_text();
pp->icm.gammaOnInput = igamma->get_active ();
if (pedited) {
pedited->icm.input = !iunchanged->get_active ();
pedited->icm.working = wnames->get_active_text()!="(Unchanged)";
pedited->icm.output = onames->get_active_text()!="(Unchanged)";
pedited->icm.gammaOnInput = !ifromfile->get_active ();
}
}
void ICMPanel::wpChanged () {
if (listener)
listener->panelChanged (EvWProfile, wnames->get_active_text ());
}
void ICMPanel::ipChanged () {
std::string profname;
if (iembedded->get_active ()) {
profname = "(embedded)";
igamma->set_sensitive (false);
}
else if (icamera->get_active ()) {
profname = "(camera)";
igamma->set_sensitive (false);
}
else {
profname = ipDialog->get_filename ();
igamma->set_sensitive (true);
}
if (listener && profname!=oldip)
listener->panelChanged (EvIProfile, profname);
oldip = profname;
}
void ICMPanel::opChanged () {
if (listener)
listener->panelChanged (EvOProfile, onames->get_active_text());
}
void ICMPanel::setRaw (bool raw) {
disableListener ();
icamera->set_active (raw);
iembedded->set_active (!raw);
icamera->set_sensitive (raw);
iembedded->set_sensitive (!raw);
enableListener ();
}
void ICMPanel::ipSelectionChanged () {
if (ipDialog->get_filename () == "")
return;
else
ipChanged ();
}
void ICMPanel::saveReferencePressed () {
if (!icmplistener)
return;
Gtk::FileChooserDialog dialog(M("TP_ICM_SAVEREFERENCEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK);
Gtk::FileFilter filter_jpg;
filter_jpg.set_name(M("SAVEDLG_JPGFILTER"));
filter_jpg.add_pattern("*.jpg");
dialog.add_filter(filter_jpg);
dialog.set_do_overwrite_confirmation (true);
if (dialog.run()==Gtk::RESPONSE_OK)
icmplistener->saveInputICCReference (dialog.get_filename());
}
void ICMPanel::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
iunchanged = Gtk::manage (new Gtk::RadioButton ("(Unchanged)"));
iunchanged->set_group (opts);
pack_start (*iunchanged, Gtk::PACK_SHRINK, 4);
reorder_child (*iunchanged, 5);
removeIfThere (this, saveRef);
onames->append_text ("(Unchanged)");
wnames->append_text ("(Unchanged)");
}

70
rtgui/icmpanel.h Executable file
View File

@@ -0,0 +1,70 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _ICMPANEL_
#define _ICMPANEL_
#include <gtkmm.h>
#include <toolpanel.h>
class ICMPanelListener {
public:
virtual void saveInputICCReference (Glib::ustring fname) {}
};
class ICMPanel : public Gtk::VBox, public ToolPanel {
private:
Gtk::RadioButton* iembedded;
Gtk::RadioButton* icamera;
Gtk::RadioButton* ifromfile;
Gtk::CheckButton* igamma;
Gtk::ComboBoxText* wnames;
Gtk::ComboBoxText* onames;
Gtk::RadioButton* ofromdir;
Gtk::RadioButton* ofromfile;
Gtk::RadioButton* iunchanged;
Gtk::FileChooserButton* ipDialog;
Gtk::FileChooserButton* opDialog;
Gtk::RadioButton::Group opts;
Gtk::Button* saveRef;
sigc::connection ipc;
Glib::ustring oldip;
ICMPanelListener* icmplistener;
public:
ICMPanel ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void wpChanged ();
void opChanged ();
void ipChanged ();
void ipSelectionChanged ();
void setRaw (bool raw);
void saveReferencePressed ();
void setICMPanelListener (ICMPanelListener* ipl) { icmplistener = ipl; }
};
#endif

63
rtgui/ilabel.cc Executable file
View File

@@ -0,0 +1,63 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <ilabel.h>
ILabel::ILabel (Glib::ustring lab) : label(lab) {}
void ILabel::on_realize() {
Gtk::DrawingArea::on_realize();
add_events(Gdk::EXPOSURE_MASK);
Glib::RefPtr<Pango::Layout> fn = create_pango_layout(label);
fn->set_markup (label);
int labw, labh;
fn->get_pixel_size (labw, labh);
set_size_request (2+labw,2+labh);
signal_style_changed().connect( sigc::mem_fun(*this, &ILabel::styleChanged) );
}
bool ILabel::on_expose_event (GdkEventExpose* event) {
Glib::RefPtr<Gtk::Style> style = get_style ();
Glib::RefPtr<Gdk::Window> window = get_window();
Glib::RefPtr<Gdk::GC> gc_ = style->get_bg_gc(get_state());
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
Gdk::Color c = style->get_fg (get_state());
cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p());
cr->rectangle (0, 0, get_width (), get_height());
cr->fill ();
Glib::RefPtr<Pango::Layout> fn = create_pango_layout (label);
fn->set_markup (label);
window->draw_layout(gc_, 1, 1, fn);
return true;
}
void ILabel::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
Glib::RefPtr<Pango::Layout> fn = create_pango_layout(label);
fn->set_markup (label);
int labw, labh;
fn->get_pixel_size (labw, labh);
set_size_request (2+labw,2+labh);
}

36
rtgui/ilabel.h Executable file
View File

@@ -0,0 +1,36 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _ILABEL_
#define _ILABEL_
#include <gtkmm.h>
class ILabel : public Gtk::DrawingArea {
Glib::ustring label;
public:
ILabel (Glib::ustring lab);
bool on_expose_event(GdkEventExpose* event);
void on_realize();
void styleChanged (const Glib::RefPtr<Gtk::Style>& style);
};
#endif

418
rtgui/imagearea.cc Executable file
View File

@@ -0,0 +1,418 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <imagearea.h>
#include <time.h>
#include <math.h>
#include <options.h>
#include <multilangmgr.h>
#include <iomanip>
#include <cropwindow.h>
ImageArea::ImageArea (ImageAreaPanel* p) : parent(p) {
showInfo = false;
infotext = "";
cropgl = NULL;
pmlistener = NULL;
focusGrabber = NULL;
mainCropWindow = NULL;
previewHandler = NULL;
lastClosedX = -1;
showClippedH = false;
showClippedS = false;
listener = NULL;
zoomPanel = Gtk::manage (new ZoomPanel (this));
indClippedPanel = Gtk::manage (new IndicateClippedPanel (this));
signal_style_changed().connect( sigc::mem_fun(*this, &ImageArea::styleChanged) );
signal_size_allocate().connect( sigc::mem_fun(*this, &ImageArea::on_resized) );
dirty = false;
}
void ImageArea::on_realize()
{
Gtk::DrawingArea::on_realize();
add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
Cairo::FontOptions cfo;
cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
get_pango_context ()->set_cairo_font_options (cfo);
}
void ImageArea::on_resized (Gtk::Allocation& req) {
if (ipc && !mainCropWindow) {
mainCropWindow = new CropWindow (this, ipc);
mainCropWindow->setDecorated (false);
mainCropWindow->setFitZoomEnabled (true);
mainCropWindow->setPosition (0, 0);
mainCropWindow->setSize (get_width(), get_height());
mainCropWindow->addCropWindowListener (this);
mainCropWindow->setCropGUIListener (cropgl);
mainCropWindow->setPointerMotionListener (pmlistener);
}
else if (ipc) {
mainCropWindow->setSize (get_width(), get_height());
}
}
void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) {
ipc = ipc_;
}
void ImageArea::setPreviewHandler (PreviewHandler* ph) {
previewHandler = ph;
}
ImageArea::~ImageArea () {
for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
delete *i;
cropWins.clear ();
if (mainCropWindow)
delete mainCropWindow;
}
void ImageArea::styleChanged (const Glib::RefPtr<Gtk::Style>& style) {
// TODO: notify all crop windows that the style has been changed
queue_draw ();
}
void ImageArea::setInfoText (Glib::ustring text) {
infotext = text;
Glib::RefPtr<Pango::Context> context = get_pango_context () ;
Pango::FontDescription fontd = context->get_font_description ();
fontd.set_weight (Pango::WEIGHT_BOLD);
fontd.set_size (12*Pango::SCALE);
context->set_font_description (fontd);
ilayout = create_pango_layout(text);
int iw, ih;
ilayout->get_pixel_size (iw, ih);
ipixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, true, 8, iw+8, ih+8);
ipixbuf->fill (128);
}
void ImageArea::infoEnabled (bool e) {
if (showInfo!=e) {
showInfo = e;
queue_draw ();
}
}
CropWindow* ImageArea::getCropWindow (int x, int y) {
CropWindow* cw = mainCropWindow;
for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
if ((*i)->isInside (x, y))
return *i;
return cw;
}
bool ImageArea::on_expose_event(GdkEventExpose* event) {
dirty = false;
if (event->count)
return true;
Glib::RefPtr<Gdk::Window> window = get_window();
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
if (mainCropWindow)
mainCropWindow->expose (cr);
if (showInfo==true && infotext!="") {
int fnw, fnh;
ilayout->get_pixel_size (fnw, fnh);
window->draw_pixbuf (get_style()->get_base_gc (Gtk::STATE_NORMAL), ipixbuf, 0, 0, 4, 4, fnw+8, fnh+8, Gdk::RGB_DITHER_NONE, 0, 0);
cr->set_source_rgb (1.0, 1.0, 1.0);
cr->move_to (8, 8);
ilayout->add_to_cairo_context (cr);
cr->fill ();
}
for (std::list<CropWindow*>::reverse_iterator i=cropWins.rbegin(); i!=cropWins.rend(); i++)
(*i)->expose (cr);
return true;
}
bool ImageArea::on_motion_notify_event (GdkEventMotion* event) {
if (focusGrabber)
focusGrabber->pointerMoved (event->x, event->y);
else {
CropWindow* cw = getCropWindow (event->x, event->y);
if (cw)
cw->pointerMoved (event->x, event->y);
}
return true;
}
bool ImageArea::on_button_press_event (GdkEventButton* event) {
if (focusGrabber)
focusGrabber->buttonPress (event->button, event->type, event->state, event->x, event->y);
else {
CropWindow* cw = getCropWindow (event->x, event->y);
if (cw)
cw->buttonPress (event->button, event->type, event->state, event->x, event->y);
}
return true;
}
bool ImageArea::on_scroll_event (GdkEventScroll* event) {
CropWindow* cw = getCropWindow (event->x, event->y);
if (cw) {
if (event->direction==GDK_SCROLL_UP)
cw->zoomIn ();
else
cw->zoomOut ();
return true;
}
return true;
}
bool ImageArea::on_button_release_event (GdkEventButton* event) {
if (focusGrabber)
focusGrabber->buttonRelease (event->button, event->type, event->state, event->x, event->y);
else {
CropWindow* cw = getCropWindow (event->x, event->y);
if (cw) {
cw->buttonRelease (event->button, event->type, event->state, event->x, event->y);
}
}
return true;
}
void ImageArea::grabFocus (CropWindow* cw) {
focusGrabber = cw;
if (cw && cw!=mainCropWindow)
cropWindowSelected (cw);
}
void ImageArea::unGrabFocus () {
focusGrabber = NULL;
}
void ImageArea::addCropWindow () {
CropWindow* cw = new CropWindow (this, ipc);
cw->setCropGUIListener (cropgl);
cw->setPointerMotionListener (pmlistener);
cropWins.push_front (cw);
if (lastClosedX<0) {
int K = 2;
int hBorder = get_width()/K/8;
int vBorder = get_height()/K/8;
int N = cropWins.size()-1;
int layer = N/K/K;
int row = K-1 - (N % (K*K)) / K;
int col = K-1 - (N % (K*K)) % K;
cw->setSize (get_width()/K - hBorder, get_height()/K - vBorder);
cw->setPosition (col*get_width()/K + hBorder/2 + layer*30, row*get_height()/K + vBorder/2 + layer*30);
}
else {
cw->setSize (lastClosedX, lastClosedY);
cw->setPosition (lastClosedW, lastClosedH);
}
mainCropWindow->setObservedCropWin (cropWins.front());
queue_draw ();
}
void ImageArea::cropWindowSelected (CropWindow* cw) {
std::list<CropWindow*>::iterator i = std::find (cropWins.begin(), cropWins.end(), cw);
if (i!=cropWins.end())
cropWins.erase (i);
cropWins.push_front (cw);
mainCropWindow->setObservedCropWin (cropWins.front());
}
void ImageArea::cropWindowClosed (CropWindow* cw) {
focusGrabber = NULL;
cw->getPosition (lastClosedX, lastClosedY);
cw->getSize (lastClosedW, lastClosedH);
std::list<CropWindow*>::iterator i = std::find (cropWins.begin(), cropWins.end(), cw);
if (i!=cropWins.end())
cropWins.erase (i);
delete cw;
if (!cropWins.empty())
mainCropWindow->setObservedCropWin (cropWins.front());
else
mainCropWindow->setObservedCropWin (NULL);
queue_draw ();
}
void ImageArea::straightenReady (double rotDeg) {
if (listener)
listener->rotateSelectionReady (rotDeg);
}
void ImageArea::spotWBSelected (int x, int y) {
if (listener)
listener->spotWBselected (x, y);
}
void ImageArea::redraw () {
if (!dirty) {
dirty = true;
queue_draw ();
}
}
void ImageArea::getScrollImageSize (int& w, int& h) {
if (mainCropWindow && ipc) {
double z = mainCropWindow->getZoom ();
w = ipc->getFullWidth() * z;
h = ipc->getFullHeight() * z;
}
else
w = h = 0;
}
void ImageArea::getScrollPosition (int& x, int& y) {
if (mainCropWindow) {
int cropX, cropY;
mainCropWindow->getCropPosition (cropX, cropY);
x = cropX*mainCropWindow->getZoom ();
y = cropY*mainCropWindow->getZoom ();
}
else
x = y = 0;
}
void ImageArea::setScrollPosition (int x, int y) {
if (mainCropWindow) {
mainCropWindow->delCropWindowListener (this);
mainCropWindow->setCropPosition (x/mainCropWindow->getZoom (), y/mainCropWindow->getZoom ());
mainCropWindow->addCropWindowListener (this);
}
}
void ImageArea::cropPositionChanged (CropWindow* cw) {
updateScrollbars ();
}
void ImageArea::cropWindowSizeChanged (CropWindow* cw) {
updateScrollbars ();
}
void ImageArea::cropZoomChanged (CropWindow* cw) {
if (cw==mainCropWindow) {
parent->zoomChanged ();
updateScrollbars ();
zoomPanel->refreshZoomLabel ();
}
}
double ImageArea::getZoom () {
if (mainCropWindow)
return mainCropWindow->getZoom ();
else
return 1.0;
}
void ImageArea::setZoom (double zoom) {
if (mainCropWindow)
mainCropWindow->setZoom (zoom);
zoomPanel->refreshZoomLabel ();
}
void ImageArea::initialImageArrived (CropWindow* cw) {
if (mainCropWindow)
mainCropWindow->zoomFit ();
}
void ImageArea::updateScrollbars () {
parent->refreshScrollBars ();
}
void ImageArea::setCropGUIListener (CropGUIListener* l) {
cropgl = l;
for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
(*i)->setCropGUIListener (cropgl);
if (mainCropWindow)
mainCropWindow->setCropGUIListener (cropgl);
}
void ImageArea::setPointerMotionListener (PointerMotionListener* pml) {
pmlistener = pml;
for (std::list<CropWindow*>::iterator i=cropWins.begin(); i!=cropWins.end(); i++)
(*i)->setPointerMotionListener (pml);
if (mainCropWindow)
mainCropWindow->setPointerMotionListener (pml);
}
ToolMode ImageArea::getToolMode () {
if (listener)
return listener->getToolBar()->getTool ();
else
return TMHand;
}
void ImageArea::setToolHand () {
if (listener)
listener->getToolBar()->setTool (TMHand);
}
int ImageArea::getSpotWBRectSize () {
if (listener)
return listener->getSpotWBRectSize ();
else
return 1;
}

125
rtgui/imagearea.h Executable file
View File

@@ -0,0 +1,125 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 __IMAGEAREA_H__
#define __IMAGEAREA_H__
#include <gtkmm.h>
#include <cropguilistener.h>
#include <imageareapanel.h>
#include <editenums.h>
#include <toolbar.h>
#include <previewhandler.h>
#include <imageareatoollistener.h>
#include <cropwindow.h>
#include <zoompanel.h>
#include <indclippedpanel.h>
class ImageAreaPanel;
class ImageArea : public Gtk::DrawingArea, public CropWindowListener {
friend class ZoomPanel;
protected:
bool showInfo;
Glib::ustring infotext;
Glib::RefPtr<Pango::Layout> ilayout;
Glib::RefPtr<Pango::Layout> deglayout;
Glib::RefPtr<Gdk::Pixbuf> ipixbuf;
bool showClippedH, showClippedS;
ImageAreaPanel* parent;
CropWindow* mainCropWindow;
std::list<CropWindow*> cropWins;
PreviewHandler* previewHandler;
rtengine::StagedImageProcessor* ipc;
int lastClosedX, lastClosedY, lastClosedW, lastClosedH;
bool dirty;
CropWindow* focusGrabber;
CropGUIListener* cropgl;
PointerMotionListener* pmlistener;
ImageAreaToolListener* listener;
CropWindow* getCropWindow (int x, int y);
public:
ZoomPanel* zoomPanel;
IndicateClippedPanel* indClippedPanel;
ImageArea (ImageAreaPanel* p);
~ImageArea ();
void setImProcCoordinator (rtengine::StagedImageProcessor* ipc_);
void getScrollImageSize (int& w, int& h);
void getScrollPosition (int& x, int& y);
void setScrollPosition (int x, int y); // called by the imageareapanel when the scrollbars have been changed
// enabling and setting text of info area
void setInfoText (Glib::ustring text);
void infoEnabled (bool e);
// widget base events
void on_realize ();
bool on_expose_event (GdkEventExpose* event);
bool on_motion_notify_event (GdkEventMotion* event);
bool on_button_press_event (GdkEventButton* event);
bool on_button_release_event (GdkEventButton* event);
bool on_scroll_event (GdkEventScroll* event);
void on_resized (Gtk::Allocation& req);
void styleChanged (const Glib::RefPtr<Gtk::Style>& style);
void updateScrollbars ();
void setCropGUIListener (CropGUIListener* l);
void setPointerMotionListener (PointerMotionListener* pml);
void setImageAreaToolListener (ImageAreaToolListener* l) { listener = l; }
void setPreviewHandler (PreviewHandler* ph);
PreviewHandler* getPreviewHandler () { return previewHandler; }
void grabFocus (CropWindow* cw);
void unGrabFocus ();
void addCropWindow ();
void cropWindowSelected (CropWindow* cw);
void cropWindowClosed (CropWindow* cw);
ToolMode getToolMode ();
void setToolHand ();
void straightenReady (double rotDeg);
void spotWBSelected (int x, int y);
int getSpotWBRectSize ();
void redraw ();
void zoomFit ();
double getZoom ();
void setZoom (double zoom);
// cropwindowlistener interface
void cropPositionChanged (CropWindow* cw);
void cropWindowSizeChanged (CropWindow* cw);
void cropZoomChanged (CropWindow* cw);
void initialImageArrived (CropWindow* cw) ;
CropWindow* getMainCropWindow () { return mainCropWindow; }
};
#endif

173
rtgui/imageareapanel.cc Executable file
View File

@@ -0,0 +1,173 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <imageareapanel.h>
ImageAreaPanel::ImageAreaPanel () : before(NULL), after(NULL) {
set_border_width (2);
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ());
hscroll = Gtk::manage (new Gtk::HScrollbar ());
vscroll = Gtk::manage (new Gtk::VScrollbar ());
imageArea = new ImageArea (this);
Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ());
frame->add (*imageArea);
frame->set_shadow_type (Gtk::SHADOW_IN );
hb1->pack_start (*frame);
hb1->pack_end (*vscroll, Gtk::PACK_SHRINK, 0);
pack_start (*hb1);
vscroll->show ();
frame->show ();
imageArea->show ();
hb1->show ();
Gtk::HBox* tmp = Gtk::manage (new Gtk::HBox ());
hb2->pack_start (*hscroll);
Gtk::Requisition vcr = vscroll->size_request ();
tmp->set_size_request (vcr.width, vcr.width);
hb2->pack_end (*tmp, Gtk::PACK_SHRINK, 0);
pack_start (*hb2,Gtk::PACK_SHRINK, 0);
hscroll->show ();
tmp->show ();
hb2->show ();
hscroll->set_update_policy (Gtk::UPDATE_CONTINUOUS);
vscroll->set_update_policy (Gtk::UPDATE_CONTINUOUS);
vscrollconn = vscroll->signal_value_changed().connect( sigc::mem_fun(*this, &ImageAreaPanel::scrollChanged) );
hscrollconn = hscroll->signal_value_changed().connect( sigc::mem_fun(*this, &ImageAreaPanel::scrollChanged) );
imageArea->signal_size_allocate().connect( sigc::mem_fun(*this, &ImageAreaPanel::imageAreaResized) );
}
ImageAreaPanel::~ImageAreaPanel () {
delete imageArea;
}
void ImageAreaPanel::configScrollBars () {
int imgw, imgh;
imageArea->getScrollImageSize (imgw, imgh);
if (imgw>0 && imgh>0) {
int iw = imageArea->get_width ();
int ih = imageArea->get_height ();
hscrollconn.block (true);
vscrollconn.block (true);
hscroll->get_adjustment()->set_upper (imgw);
vscroll->get_adjustment()->set_upper (imgh);
hscroll->get_adjustment()->set_lower (0);
vscroll->get_adjustment()->set_lower (0);
hscroll->get_adjustment()->set_step_increment (imgw/100);
vscroll->get_adjustment()->set_step_increment (imgh/100);
hscroll->get_adjustment()->set_page_increment (imgw/5);
vscroll->get_adjustment()->set_page_increment (imgh/5);
hscroll->get_adjustment()->set_page_size (iw);
vscroll->get_adjustment()->set_page_size (ih);
int x, y;
imageArea->getScrollPosition (x, y);
hscroll->set_value (x);
vscroll->set_value (y);
if (before && this==after)
before->synchronize ();
else if (after && this==before)
after->synchronize ();
hscrollconn.block (false);
vscrollconn.block (false);
}
}
void ImageAreaPanel::refreshScrollBars () {
configScrollBars ();
queue_draw ();
}
void ImageAreaPanel::imageAreaResized (Gtk::Allocation& req) {
configScrollBars ();
queue_draw ();
}
void ImageAreaPanel::scrollChanged () {
imageArea->setScrollPosition ((int)(hscroll->get_value()), (int)(vscroll->get_value()));
imageArea->queue_draw ();
#ifdef _WIN32
gdk_window_process_updates (get_window()->gobj(), true);
#endif
if (before && this==after)
before->synchronize ();
else if (after && this==before)
after->synchronize ();
}
void ImageAreaPanel::setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft) {
before = bef;
after = aft;
configScrollBars ();
}
void ImageAreaPanel::zoomChanged () {
if (after && this==before)
after->imageArea->setZoom (imageArea->getZoom ());
else if (before && this==after)
before->imageArea->setZoom (imageArea->getZoom ());
}
void ImageAreaPanel::synchronize () {
hscrollconn.block (true);
vscrollconn.block (true);
if (after && this==before) {
int imgw, imgh, x, y;
after->imageArea->getScrollImageSize (imgw, imgh);
after->imageArea->getScrollPosition (x, y);
int bimgw, bimgh;
imageArea->getScrollImageSize (bimgw, bimgh);
imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh);
imageArea->queue_draw ();
}
else if (before && this==after) {
int imgw, imgh, x, y;
before->imageArea->getScrollImageSize (imgw, imgh);
before->imageArea->getScrollPosition (x, y);
int bimgw, bimgh;
imageArea->getScrollImageSize (bimgw, bimgh);
imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh);
imageArea->queue_draw ();
}
hscrollconn.block (false);
vscrollconn.block (false);
}

53
rtgui/imageareapanel.h Executable file
View File

@@ -0,0 +1,53 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _IMAGEAREAPANEL_
#define _IMAGEAREAPANEL_
#include <imagearea.h>
class ImageArea;
class ImageAreaPanel : public Gtk::VBox {
protected:
Gtk::HScrollbar* hscroll;
Gtk::VScrollbar* vscroll;
sigc::connection hscrollconn;
sigc::connection vscrollconn;
void synchronize ();
void configScrollBars ();
ImageAreaPanel *before, *after;
public:
ImageArea* imageArea;
ImageAreaPanel ();
~ImageAreaPanel ();
void scrollChanged ();
void imageAreaResized (Gtk::Allocation& req);
void refreshScrollBars ();
void zoomChanged ();
void setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft);
};
#endif

38
rtgui/imageareatoollistener.h Executable file
View File

@@ -0,0 +1,38 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _IMAGEAREATOOLLISTENER_
#define _IMAGEAREATOOLLISTENER_
#include <toolbar.h>
#include <thumbnail.h>
#include <cropguilistener.h>
class ImageAreaToolListener {
public:
virtual void spotWBselected (int x, int y, Thumbnail* thm=NULL) {}
virtual int getSpotWBRectSize () { return 8; }
virtual void cropSelectionReady () {}
virtual void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL) {}
virtual ToolBar* getToolBar () { return NULL; }
virtual CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return NULL; }
};
#endif

51
rtgui/indclippedpanel.cc Executable file
View File

@@ -0,0 +1,51 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <indclippedpanel.h>
#include <options.h>
#include <multilangmgr.h>
#include <imagearea.h>
IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) {
indclippedh = Gtk::manage (new Gtk::ToggleButton ());
indclippedh->set_relief(Gtk::RELIEF_NONE);
indclippedh->add (*Gtk::manage (new Gtk::Image (argv0+"/images/warnhl.png")));
indclippedh->set_tooltip_text (M("MAIN_TOOLTIP_INDCLIPPEDH"));
indclippeds = Gtk::manage (new Gtk::ToggleButton ());
indclippeds->set_relief(Gtk::RELIEF_NONE);
indclippeds->add (*Gtk::manage (new Gtk::Image (argv0+"/images/warnsh.png")));
indclippeds->set_tooltip_text (M("MAIN_TOOLTIP_INDCLIPPEDS"));
indclippedh->set_active (options.showClippedHighlights);
indclippeds->set_active (options.showClippedShadows);
pack_start (*indclippedh, Gtk::PACK_SHRINK, 0);
pack_start (*indclippeds, Gtk::PACK_SHRINK, 0);
indclippedh->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) );
indclippeds->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) );
show_all ();
}
void IndicateClippedPanel::buttonToggled () {
imageArea->queue_draw ();
}

41
rtgui/indclippedpanel.h Executable file
View File

@@ -0,0 +1,41 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 _INDCLIPPEDPANEL_
#define _INDCLIPPEDPANEL_
#include <gtkmm.h>
class ImageArea;
class IndicateClippedPanel : public Gtk::HBox {
protected:
Gtk::ToggleButton* indclippedh;
Gtk::ToggleButton* indclippeds;
ImageArea* imageArea;
public:
IndicateClippedPanel (ImageArea* ia);
void buttonToggled ();
bool showClippedShadows () { return indclippeds->get_active (); }
bool showClippedHighlights () { return indclippedh->get_active (); }
};
#endif

Some files were not shown because too many files have changed in this diff Show More