diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 11ca6f2ea..93c6b6604 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -21,10 +21,6 @@ #include #include "safegtk.h" -#ifndef GLIBMM_EXCEPTIONS_ENABLED -#include -#endif - using namespace rtengine; extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile); diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc index e072a5356..a84b73536 100644 --- a/rtengine/safegtk.cc +++ b/rtengine/safegtk.cc @@ -76,23 +76,18 @@ Cairo::RefPtr safe_create_from_png(const Glib::ustring& fil Glib::RefPtr safe_query_file_info (Glib::RefPtr &file) { Glib::RefPtr info; -#ifdef GLIBMM_EXCEPTIONS_ENABLED try { info = file->query_info(); } catch (...) { } -#else - std::auto_ptr error; - info = file->query_info("*", Gio::FILE_QUERY_INFO_NONE, error); -#endif return info; } Glib::RefPtr safe_next_file (Glib::RefPtr &dirList) { Glib::RefPtr info; -#ifdef GLIBMM_EXCEPTIONS_ENABLED + bool retry; Glib::ustring last_error = ""; @@ -113,42 +108,15 @@ Glib::RefPtr safe_next_file (Glib::RefPtr &d } } while (retry); -#else - bool retry; - Glib::ustring last_error = ""; - - do { - retry = false; - std::auto_ptr error; - Glib::RefPtr cancellable; - info = dirList->next_file(cancellable, error); - - if (!info && error.get()) { - printf ("%s\n", error.what().c_str()); - retry = (error.what() != last_error); - last_error = error.what(); - } - } while (retry); - -#endif return info; } -#ifdef GLIBMM_EXCEPTIONS_ENABLED # define SAFE_ENUMERATOR_CODE_START \ do{try { if ((dirList = dir->enumerate_children ())) \ for (Glib::RefPtr info = safe_next_file(dirList); info; info = safe_next_file(dirList)) { # define SAFE_ENUMERATOR_CODE_END \ }} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0) -#else -# define SAFE_ENUMERATOR_CODE_START \ - do{std::auto_ptr error; Glib::RefPtr cancellable; \ - if ((dirList = dir->enumerate_children (cancellable, "*", Gio::FILE_QUERY_INFO_NONE, error))) \ - for (Glib::RefPtr info = safe_next_file(dirList); info; info = safe_next_file(dirList)) { - -# define SAFE_ENUMERATOR_CODE_END } if (error.get()) printf ("%s\n", error->what().c_str());}while (0) -#endif /* * safe_build_file_list can now filter out at the source all files that doesn't have the extensions specified (if provided) @@ -223,8 +191,8 @@ void safe_build_subdir_list (Glib::RefPtr &dir, std::vector error; - utf8_str = locale_to_utf8(src, error); - if (error.get()) { - utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1", "?", error); - } - } -#endif //GLIBMM_EXCEPTIONS_ENABLED -#else utf8_str = Glib::filename_to_utf8(src); + #endif + return utf8_str; } Glib::ustring safe_locale_to_utf8 (const std::string& src) { Glib::ustring utf8_str; -#ifdef GLIBMM_EXCEPTIONS_ENABLED try { utf8_str = Glib::locale_to_utf8(src); @@ -259,38 +219,17 @@ Glib::ustring safe_locale_to_utf8 (const std::string& src) utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1", "?"); } -#else - { - std::auto_ptr error; - utf8_str = locale_to_utf8(src, error); - - if (error.get()) { - utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1", "?", error); - } - } -#endif //GLIBMM_EXCEPTIONS_ENABLED return utf8_str; } std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str) { std::string str; -#ifdef GLIBMM_EXCEPTIONS_ENABLED try { str = Glib::locale_from_utf8(utf8_str); - } catch (const Glib::Error& e) { - //str = Glib::convert_with_fallback(utf8_str, "ISO-8859-1", "UTF-8", "?"); - } + } catch (Glib::Error&) {} -#else - { - std::auto_ptr error; - str = Glib::locale_from_utf8(utf8_str, error); - /*if (error.get()) - {str = Glib::convert_with_fallback(utf8_str, "ISO-8859-1", "UTF-8", "?", error);}*/ - } -#endif //GLIBMM_EXCEPTIONS_ENABLED return str; } @@ -298,7 +237,6 @@ bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) { std::string cmd; bool success = false; -#ifdef GLIBMM_EXCEPTIONS_ENABLED try { cmd = Glib::filename_from_utf8(cmd_utf8); @@ -309,22 +247,6 @@ bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) printf ("%s\n", ex.what().c_str()); } -#else - std::auto_ptr error; - cmd = Glib::filename_from_utf8(cmd_utf8, error); - - if (!error.get()) { - printf ("command line: %s\n", cmd.c_str()); - Glib::spawn_command_line_async (cmd, error); - } - - if (error.get()) { - printf ("%s\n", error->what().c_str()); - } else { - success = true; - } - -#endif return success; } diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 8dc843a8e..53a0629fd 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -21,6 +21,7 @@ #include #include "../rtengine/rt_math.h" +#include #include #include #include @@ -37,13 +38,13 @@ using namespace std; using namespace rtengine; -BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(NULL), fileCatalog(aFileCatalog), sequence(0), listener(NULL) +BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(NULL), fileCatalog(aFileCatalog), sequence(0), listener(NULL), + pmenu (new Gtk::Menu ()) { location = THLOC_BATCHQUEUE; int p = 0; - pmenu = new Gtk::Menu (); pmenu->attach (*Gtk::manage(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPENINEDITOR"))), 0, 1, p, p + 1); p++; @@ -79,9 +80,9 @@ BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(NULL), fileCatal cancel->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); open->signal_activate().connect(sigc::mem_fun(*this, &BatchQueue::openLastSelectedItemInEditor)); - 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)); + cancel->signal_activate().connect (std::bind (&BatchQueue::cancelItems, this, selected)); + head->signal_activate().connect (std::bind (&BatchQueue::headItems, this, selected)); + tail->signal_activate().connect (std::bind (&BatchQueue::tailItems, this, selected)); selall->signal_activate().connect (sigc::mem_fun(*this, &BatchQueue::selectAll)); setArrangement (ThumbBrowserBase::TB_Vertical); @@ -99,20 +100,18 @@ BatchQueue::~BatchQueue () } fd.clear (); - - delete pmenu; } void BatchQueue::resizeLoadedQueue() { - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif - for (size_t i = 0; i < fd.size(); i++) { - fd.at(i)->resize(getThumbnailHeight()); - } + const auto height = getThumbnailHeight (); + + for (const auto entry : fd) + entry->resize(height); } // Reduce the max size of a thumb, since thumb is processed synchronously on adding to queue @@ -161,328 +160,220 @@ bool BatchQueue::keyPressed (GdkEventKey* event) openLastSelectedItemInEditor(); return true; } else if (event->keyval == GDK_Home) { - headItems (&selected); + headItems (selected); return true; } else if (event->keyval == GDK_End) { - tailItems (&selected); + tailItems (selected); return true; } else if (event->keyval == GDK_Delete) { - cancelItems (&selected); + cancelItems (selected); return true; } return false; } -void BatchQueue::addEntries ( std::vector &entries, bool head, bool save) +void BatchQueue::addEntries (const std::vector& entries, bool head, bool save) { { - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif - for( std::vector::iterator entry = entries.begin(); entry != entries.end(); entry++ ) { - (*entry)->setParent (this); + for (const auto entry : entries) { - // BatchQueueButtonSet HAVE TO be added before resizing to take them into account - BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (*entry); + entry->setParent (this); + + // BatchQueueButtonSet have to be added before resizing to take them into account + const auto bqbs = new BatchQueueButtonSet (entry); bqbs->setButtonListener (this); - (*entry)->addButtonSet (bqbs); + entry->addButtonSet (bqbs); - (*entry)->resize (getThumbnailHeight()); // batch queue might have smaller, restricted size - Glib::ustring tempFile = getTempFilenameForParams( (*entry)->filename ); + // batch queue might have smaller, restricted size + entry->resize (getThumbnailHeight()); // recovery save - if( !(*entry)->params.save( tempFile ) ) { - (*entry)->savedParamsFile = tempFile; - } + const auto tempFile = getTempFilenameForParams (entry->filename); - (*entry)->selected = false; + if (!entry->params.save (tempFile)) + entry->savedParamsFile = tempFile; - if (!head) { - fd.push_back (*entry); - } else { - std::vector::iterator pos; + entry->selected = false; - for (pos = fd.begin(); pos != fd.end(); pos++) - if (!(*pos)->processing) { - fd.insert (pos, *entry); - break; - } + // insert either at the end, or before the first non-processing entry + auto pos = fd.end (); - if (pos == fd.end()) { - fd.push_back (*entry); - } - } + if (head) + pos = std::find_if (fd.begin (), fd.end (), [] (const ThumbBrowserEntryBase* fdEntry) { return !fdEntry->processing; }); - if ((*entry)->thumbnail) { - (*entry)->thumbnail->imageEnqueued (); - } + fd.insert (pos, entry); + + if (entry->thumbnail) + entry->thumbnail->imageEnqueued (); } } - if (save) { - saveBatchQueue( ); - } + if (save) + saveBatchQueue (); - redraw(); + redraw (); notifyListener (false); } -bool BatchQueue::saveBatchQueue( ) +bool BatchQueue::saveBatchQueue () { - Glib::ustring savedQueueFile; - savedQueueFile = options.rtdir + "/batch/queue.csv"; - FILE *f = safe_g_fopen (savedQueueFile, "wt"); + const auto fileName = Glib::build_filename (options.rtdir, "batch", "queue.csv"); - if (f == NULL) { + std::ofstream file (fileName, std::ios::trunc); + + if (!file.is_open ()) return false; - } { - // TODO: Check for Linux #if PROTECT_VECTORS MYREADERLOCK(l, entryRW); #endif + if (fd.empty ()) + return true; - if (fd.size()) - // The column's header is mandatory (the first line will be skipped when loaded) - fprintf(f, "input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|" - "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|\n"); + // The column's header is mandatory (the first line will be skipped when loaded) + file << "input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|" + << "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|" + << std::endl; // method is already running with entryLock, so no need to lock again - for (std::vector::iterator pos = fd.begin(); pos != fd.end(); pos++) { - BatchQueueEntry* bqe = reinterpret_cast(*pos); + for (const auto fdEntry : fd) { + + const auto entry = static_cast (fdEntry); + const auto& saveFormat = entry->saveFormat; + // Warning: for code's simplicity in loadBatchQueue, each field must end by the '|' character, safer than ';' or ',' since it can't be used in paths - fprintf(f, "%s|%s|%s|%s|%d|%d|%d|%d|%d|%d|%d|%d|\n", - bqe->filename.c_str(), bqe->savedParamsFile.c_str(), bqe->outFileName.c_str(), bqe->saveFormat.format.c_str(), - bqe->saveFormat.jpegQuality, bqe->saveFormat.jpegSubSamp, - bqe->saveFormat.pngBits, bqe->saveFormat.pngCompression, - bqe->saveFormat.tiffBits, bqe->saveFormat.tiffUncompressed, - bqe->saveFormat.saveParams, bqe->forceFormatOpts - ); + file << entry->filename << '|' << entry->savedParamsFile << '|' << entry->outFileName << '|' << saveFormat.format << '|' + << saveFormat.jpegQuality << '|' << saveFormat.jpegSubSamp << '|' + << saveFormat.pngBits << '|' << saveFormat.pngCompression << '|' + << saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|' + << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' + << std::endl; } } - fclose (f); return true; } -bool BatchQueue::loadBatchQueue( ) +bool BatchQueue::loadBatchQueue () { - Glib::ustring savedQueueFile; - savedQueueFile = options.rtdir + "/batch/queue.csv"; - FILE *f = safe_g_fopen (savedQueueFile, "rt"); + const auto fileName = Glib::build_filename (options.rtdir, "batch", "queue.csv"); - if (f != NULL) { - char *buffer = new char[1024]; - unsigned numLoaded = 0; - // skipping the first line - bool firstLine = true; + std::ifstream file (fileName); + if (file.is_open ()) { // Yes, it's better to get the lock for the whole file reading, // to update the list in one shot without any other concurrent access! - - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif - while (fgets (buffer, 1024, f)) { + std::string row, column; + std::vector values; - if (firstLine) { - // skipping the column's title line - firstLine = false; + // skipping the first row + std::getline (file, row); + + while (std::getline (file, row)) { + + std::istringstream line (row); + + values.clear (); + + while (std::getline(line, column, '|')) { + values.push_back (column); + } + + auto value = values.begin (); + + const auto nextStringOr = [&] (const Glib::ustring& defaultValue) -> Glib::ustring + { + return value != values.end () ? Glib::ustring(*value++) : defaultValue; + }; + const auto nextIntOr = [&] (int defaultValue) -> int + { + try { + return value != values.end () ? std::stoi(*value++) : defaultValue; + } + catch (std::exception&) { + return defaultValue; + } + }; + + const auto source = nextStringOr (Glib::ustring ()); + const auto paramsFile = nextStringOr (Glib::ustring ()); + + if (source.empty () || paramsFile.empty ()) continue; + + const auto outputFile = nextStringOr (Glib::ustring ()); + const auto saveFmt = nextStringOr (options.saveFormat.format); + const auto jpegQuality = nextIntOr (options.saveFormat.jpegQuality); + const auto jpegSubSamp = nextIntOr (options.saveFormat.jpegSubSamp); + const auto pngBits = nextIntOr (options.saveFormat.pngBits); + const auto pngCompression = nextIntOr (options.saveFormat.pngCompression); + const auto tiffBits = nextIntOr (options.saveFormat.tiffBits); + const auto tiffUncompressed = nextIntOr (options.saveFormat.tiffUncompressed); + const auto saveParams = nextIntOr (options.saveFormat.saveParams); + const auto forceFormatOpts = nextIntOr (options.forceFormatOpts); + + rtengine::procparams::ProcParams pparams; + + if (pparams.load (paramsFile)) + continue; + + auto thumb = CacheManager::getInstance ()->getEntry (source); + + if (!thumb) + continue; + + auto job = rtengine::ProcessingJob::create (source, thumb->getType () == FT_Raw, pparams); + + auto prevh = getMaxThumbnailHeight (); + auto prevw = prevh; + thumb->getThumbnailSize (prevw, prevh, &pparams); + + auto entry = new BatchQueueEntry (job, pparams, source, prevw, prevh, thumb); + thumb->decreaseRef (); // Removing the refCount acquired by cacheMgr->getEntry + entry->setParent (this); + + // BatchQueueButtonSet have to be added before resizing to take them into account + auto bqbs = new BatchQueueButtonSet (entry); + bqbs->setButtonListener (this); + entry->addButtonSet (bqbs); + + entry->savedParamsFile = paramsFile; + entry->selected = false; + entry->outFileName = outputFile; + + if (!outputFile.empty ()) { + auto& saveFormat = entry->saveFormat; + saveFormat.format = saveFmt; + saveFormat.jpegQuality = jpegQuality; + saveFormat.jpegSubSamp = jpegSubSamp; + saveFormat.pngBits = pngBits; + saveFormat.pngCompression = pngCompression; + saveFormat.tiffBits = tiffBits; + saveFormat.tiffUncompressed = tiffUncompressed != 0; + saveFormat.saveParams = saveParams != 0; + entry->forceFormatOpts = forceFormatOpts != 0; + } else { + entry->forceFormatOpts = false; } - size_t pos; - Glib::ustring source; - Glib::ustring paramsFile; - Glib::ustring outputFile; - Glib::ustring saveFmt(options.saveFormat.format); - int jpegQuality = options.saveFormat.jpegQuality, jpegSubSamp = options.saveFormat.jpegSubSamp; - int pngBits = options.saveFormat.pngBits, pngCompression = options.saveFormat.pngCompression; - int tiffBits = options.saveFormat.tiffBits, tiffUncompressed = options.saveFormat.tiffUncompressed; - int saveParams = options.saveFormat.saveParams; - int forceFormatOpts = options.forceFormatOpts; - - Glib::ustring currLine(buffer); - int a = 0; - - if (currLine.rfind('\n') != Glib::ustring::npos) { - a++; - } - - if (currLine.rfind('\r') != Glib::ustring::npos) { - a++; - } - - if (a) { - currLine = currLine.substr(0, currLine.length() - a); - } - - // Looking for the image's full path - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - source = currLine.substr(0, pos); - currLine = currLine.substr(pos + 1); - - // Looking for the procparams' full path - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - paramsFile = currLine.substr(0, pos); - currLine = currLine.substr(pos + 1); - - // Looking for the full output path; if empty, it'll use the template string - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - outputFile = currLine.substr(0, pos); - currLine = currLine.substr(pos + 1); - - // No need to bother reading the last options, they will be ignored if outputFile is empty! - if (!outputFile.empty()) { - - // Looking for the saving format - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - saveFmt = currLine.substr(0, pos); - currLine = currLine.substr(pos + 1); - - // Looking for the jpeg quality - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - jpegQuality = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking for the jpeg subsampling - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - jpegSubSamp = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking for the png bit depth - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - pngBits = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking for the png compression - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - pngCompression = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking for the tiff bit depth - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - tiffBits = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking for the tiff uncompression - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - tiffUncompressed = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking out if we have to save the procparams - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - saveParams = atoi(currLine.substr(0, pos).c_str()); - currLine = currLine.substr(pos + 1); - - // Looking out if we have to to use the format options - pos = currLine.find('|'); - - if (pos != Glib::ustring::npos) { - forceFormatOpts = atoi(currLine.substr(0, pos).c_str()); - // currLine = currLine.substr(pos+1); - - } - } - } - } - } - } - } - } - } - } - } - } - } - - if( !source.empty() && !paramsFile.empty() ) { - rtengine::procparams::ProcParams pparams; - - if( pparams.load( paramsFile ) ) { - continue; - } - - ::Thumbnail *thumb = cacheMgr->getEntry( source ); - - if( thumb ) { - rtengine::ProcessingJob* job = rtengine::ProcessingJob::create(source, thumb->getType() == FT_Raw, pparams); - - int prevh = getMaxThumbnailHeight(); - int prevw = prevh; - thumb->getThumbnailSize (prevw, prevh, &pparams); - - BatchQueueEntry *entry = new BatchQueueEntry(job, pparams, source, prevw, prevh, thumb); - thumb->decreaseRef(); // Removing the refCount acquired by cacheMgr->getEntry - entry->setParent(this); - - // BatchQueueButtonSet HAVE TO be added before resizing to take them into account - BatchQueueButtonSet* bqbs = new BatchQueueButtonSet(entry); - bqbs->setButtonListener(this); - entry->addButtonSet(bqbs); - - //entry->resize(getThumbnailHeight()); - entry->savedParamsFile = paramsFile; - entry->selected = false; - entry->outFileName = outputFile; - - if (!outputFile.empty()) { - entry->saveFormat.format = saveFmt; - entry->saveFormat.jpegQuality = jpegQuality; - entry->saveFormat.jpegSubSamp = jpegSubSamp; - entry->saveFormat.pngBits = pngBits; - entry->saveFormat.pngCompression = pngCompression; - entry->saveFormat.tiffBits = tiffBits; - entry->saveFormat.tiffUncompressed = tiffUncompressed != 0; - entry->saveFormat.saveParams = saveParams != 0; - entry->forceFormatOpts = forceFormatOpts != 0; - } else { - entry->forceFormatOpts = false; - } - - fd.push_back(entry); - - numLoaded++; - } - } + fd.push_back (entry); } - - delete [] buffer; - fclose(f); } - redraw(); - notifyListener(false); + redraw (); + notifyListener (false); - return !fd.empty(); + return !fd.empty (); } Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename ) @@ -509,107 +400,106 @@ int cancelItemUI (void* data) return 0; } -void BatchQueue::cancelItems (std::vector* items) +void BatchQueue::cancelItems (const std::vector& items) { { - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif - for (size_t i = 0; i < items->size(); i++) { - BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + for (const auto item : items) { - if (entry->processing) { + const auto entry = static_cast (item); + + if (entry->processing) continue; - } - std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + const auto pos = std::find (fd.begin (), fd.end (), entry); - if (pos != fd.end()) { - fd.erase (pos); - rtengine::ProcessingJob::destroy (entry->job); + if (pos == fd.end ()) + continue; - if (entry->thumbnail) { - entry->thumbnail->imageRemovedFromQueue (); - } + fd.erase (pos); - g_idle_add (cancelItemUI, entry); - } + rtengine::ProcessingJob::destroy (entry->job); + + if (entry->thumbnail) + entry->thumbnail->imageRemovedFromQueue (); + + g_idle_add (cancelItemUI, entry); } - for (size_t i = 0; i < fd.size(); i++) { - fd[i]->selected = false; - } + for (const auto entry : fd) + entry->selected = false; - lastClicked = NULL; + lastClicked = nullptr; selected.clear (); } - saveBatchQueue( ); + saveBatchQueue (); redraw (); notifyListener (false); } -void BatchQueue::headItems (std::vector* items) +void BatchQueue::headItems (const std::vector& items) { { - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif + for (auto item = items.rbegin(); item != items.rend(); ++item) { - for (int i = items->size() - 1; i >= 0; i--) { - BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + const auto entry = static_cast (*item); - if (entry->processing) { + if (entry->processing) continue; - } - std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + const auto pos = std::find (fd.begin (), fd.end (), entry); - if (pos != fd.end() && pos != fd.begin()) { - fd.erase (pos); + if (pos == fd.end () || pos == fd.begin ()) + continue; - // 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; - } - } + fd.erase (pos); + + // find the first item that is not under processing + const auto newPos = std::find_if (fd.begin (), fd.end (), [] (const ThumbBrowserEntryBase* fdEntry) { return !fdEntry->processing; }); + + fd.insert (newPos, entry); } } - saveBatchQueue( ); + + saveBatchQueue (); redraw (); } -void BatchQueue::tailItems (std::vector* items) +void BatchQueue::tailItems (const std::vector& items) { { - // TODO: Check for Linux #if PROTECT_VECTORS MYWRITERLOCK(l, entryRW); #endif - for (size_t i = 0; i < items->size(); i++) { - BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + for (const auto item : items) { - if (entry->processing) { + const auto entry = static_cast (item); + + if (entry->processing) continue; - } - std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + const auto pos = std::find (fd.begin (), fd.end (), entry); - if (pos != fd.end()) { - fd.erase (pos); - fd.push_back (entry); - } + if (pos == fd.end ()) + continue; + + fd.erase (pos); + + fd.push_back (entry); } } - saveBatchQueue( ); + + saveBatchQueue (); redraw (); } @@ -1034,11 +924,11 @@ void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionDa bqe.push_back (static_cast(actionData)); if (actionCode == 10) { // cancel - cancelItems (&bqe); + cancelItems (bqe); } else if (actionCode == 8) { // to head - headItems (&bqe); + headItems (bqe); } else if (actionCode == 9) { // to tail - tailItems (&bqe); + tailItems (bqe); } } diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 4e97ebc9f..38fbee1f8 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -57,7 +57,7 @@ protected: Gtk::ImageMenuItem* tail; Gtk::MenuItem* selall; Gtk::MenuItem* open; - Gtk::Menu* pmenu; + std::unique_ptr pmenu; Glib::RefPtr pmaccelgroup; @@ -65,17 +65,17 @@ protected: Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format); Glib::ustring getTempFilenameForParams( const Glib::ustring filename ); - bool saveBatchQueue( ); + bool saveBatchQueue (); void notifyListener (bool queueEmptied); public: BatchQueue (FileCatalog* aFileCatalog); ~BatchQueue (); - void addEntries (std::vector &entries, bool head = false, bool save = true); - void cancelItems (std::vector* items); - void headItems (std::vector* items); - void tailItems (std::vector* items); + void addEntries (const std::vector& entries, bool head = false, bool save = true); + void cancelItems (const std::vector& items); + void headItems (const std::vector& items); + void tailItems (const std::vector& items); void selectAll (); void openItemInEditor(ThumbBrowserEntryBase* item); void openLastSelectedItemInEditor(); diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index c1915436d..d524e0c4d 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -423,7 +423,7 @@ Glib::ustring CurveEditorSubGroup::outputFile () { Gtk::FileChooserDialog dialog(M("CURVEEDITOR_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); - FileChooserLastFolderPersister persister(&dialog, curveDir); + bindCurrentFolder (dialog, curveDir); dialog.set_current_name (lastFilename); dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); @@ -468,7 +468,7 @@ Glib::ustring CurveEditorSubGroup::inputFile () { Gtk::FileChooserDialog dialog(M("CURVEEDITOR_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN); - FileChooserLastFolderPersister persister(&dialog, curveDir); + bindCurrentFolder (dialog, curveDir); dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); dialog.add_button(Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index e16817cb6..9edde1bbc 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -31,7 +31,7 @@ DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_L hbdf = Gtk::manage(new Gtk::HBox()); hbdf->set_spacing(4); darkFrameFile = Gtk::manage(new MyFileChooserButton(M("TP_DARKFRAME_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - darkFrameFilePersister.reset(new FileChooserLastFolderPersister(darkFrameFile, options.lastDarkframeDir)); + bindCurrentFolder (*darkFrameFile, options.lastDarkframeDir); dfLabel = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); btnReset = Gtk::manage(new Gtk::Button()); btnReset->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h index 5f8e32d90..fd0dc9fde 100644 --- a/rtgui/darkframe.h +++ b/rtgui/darkframe.h @@ -39,7 +39,6 @@ class DarkFrame : public ToolParamBlock, public FoldableToolPanel protected: MyFileChooserButton *darkFrameFile; - std::auto_ptr darkFrameFilePersister; Gtk::HBox *hbdf; Gtk::Button *btnReset; Gtk::Label *dfLabel; diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index 88bd2aee4..76e351569 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -61,20 +61,12 @@ EditWindow::EditWindow (RTWindow* p) : parent(p) , isFullscreen(false) Glib::ustring fName = "rt-logo.png"; Glib::ustring fullPath = RTImage::findIconAbsolutePath(fName); -#ifdef GLIBMM_EXCEPTIONS_ENABLED - try { set_default_icon_from_file (fullPath); } catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } -#else - { - std::auto_ptr error; - set_default_icon_from_file (fullPath, error); - } -#endif //GLIBMM_EXCEPTIONS_ENABLED set_title_decorated(""); property_allow_shrink() = true; set_modal(false); diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 8bb1d69bb..fc0b3b9ae 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -854,7 +854,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) if( !mselected.empty() ) { rtengine::procparams::ProcParams pp = mselected[0]->thumbnail->getProcParams(); Gtk::FileChooserDialog fc("Dark Frame", Gtk::FILE_CHOOSER_ACTION_OPEN ); - FileChooserLastFolderPersister persister(&fc, options.lastDarkframeDir); + bindCurrentFolder (fc, options.lastDarkframeDir); fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); @@ -930,7 +930,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) if( !mselected.empty() ) { rtengine::procparams::ProcParams pp = mselected[0]->thumbnail->getProcParams(); Gtk::FileChooserDialog fc("Flat Field", Gtk::FILE_CHOOSER_ACTION_OPEN ); - FileChooserLastFolderPersister persister(&fc, options.lastFlatfieldDir); + bindCurrentFolder (fc, options.lastFlatfieldDir); fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index cc8035fa8..8609bea73 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -31,7 +31,7 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L hbff = Gtk::manage(new Gtk::HBox()); hbff->set_spacing(2); flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - flatFieldFilePersister.reset(new FileChooserLastFolderPersister(flatFieldFile, options.lastFlatfieldDir)); + bindCurrentFolder (*flatFieldFile, options.lastFlatfieldDir); ffLabel = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); flatFieldFileReset = Gtk::manage(new Gtk::Button()); flatFieldFileReset->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index c760433ec..162360b9a 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -41,7 +41,6 @@ class FlatField : public ToolParamBlock, public AdjusterListener, public Foldabl protected: MyFileChooserButton *flatFieldFile; - std::auto_ptr flatFieldFilePersister; Gtk::Label *ffLabel; Gtk::Label *ffInfo; Gtk::Button *flatFieldFileReset; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 141273179..9ca9af3e9 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1013,34 +1013,18 @@ bool MyFileChooserButton::on_scroll_event (GdkEventScroll* event) return false; } -FileChooserLastFolderPersister::FileChooserLastFolderPersister( - Gtk::FileChooser* chooser, Glib::ustring& folderVariable) : - chooser(chooser), folderVariable(folderVariable) +void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable) { - assert(chooser != NULL); + chooser.signal_selection_changed ().connect ([&]() + { + const auto current_folder = chooser.get_current_folder (); - selectionChangedConnetion = chooser->signal_selection_changed().connect( - sigc::mem_fun(*this, - &FileChooserLastFolderPersister::selectionChanged)); - - if (!folderVariable.empty()) { - chooser->set_current_folder(folderVariable); - } - -} - -FileChooserLastFolderPersister::~FileChooserLastFolderPersister() -{ - -} - -void FileChooserLastFolderPersister::selectionChanged() -{ - - if (!chooser->get_current_folder().empty()) { - folderVariable = chooser->get_current_folder(); - } + if (!current_folder.empty ()) + variable = current_folder; + }); + if (!variable.empty ()) + chooser.set_current_folder (variable); } TextOrIcon::TextOrIcon (Glib::ustring fname, Glib::ustring labelTx, Glib::ustring tooltipTx, TOITypes type) diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 79f050c2f..c43d85b07 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -313,39 +313,9 @@ public: }; /** - * A class which maintains the last folder for a FileChooserDialog or Button by - * caching it in a a variable (which can be persisted externally). - * Each time the user selects a file or folder, the provided variable is updated - * with the associated folder. The path found in the variable is set in the - * dialog instance at constructions time of this object. + * @brief A helper method to connect the current folder property of a file chooser to an arbitrary variable. */ -class FileChooserLastFolderPersister: public Glib::Object -{ -public: - - /** - * Installs this persister on the provided GtkFileChooser instance and - * applies the current folder found in @p folderVariable for the dialog. - * - * @param chooser file chooser to maintain - * @param folderVariable variable storage to use for this dialog - */ - FileChooserLastFolderPersister(Gtk::FileChooser* chooser, Glib::ustring& folderVariable); - - virtual ~FileChooserLastFolderPersister(); - -private: - - /** - * Signal handler for the GtkFileChooser selection action. - */ - void selectionChanged(); - - Gtk::FileChooser* chooser; - Glib::ustring& folderVariable; - sigc::connection selectionChangedConnetion; - -}; +void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable); typedef enum RTUpdatePolicy { RTUP_STATIC, diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 584a99a22..b21ebf751 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -37,7 +37,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch ipDialog = Gtk::manage (new MyFileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); ipDialog->set_tooltip_text (M("TP_ICM_INPUTCUSTOM_TOOLTIP")); - ipDialogPersister.reset(new FileChooserLastFolderPersister(ipDialog, options.lastIccDir)); + bindCurrentFolder (*ipDialog, options.lastIccDir); // ------------------------------- Input profile @@ -945,7 +945,7 @@ void ICMPanel::saveReferencePressed () } Gtk::FileChooserDialog dialog(M("TP_ICM_SAVEREFERENCE"), Gtk::FILE_CHOOSER_ACTION_SAVE); - FileChooserLastFolderPersister persister(&dialog, options.lastProfilingReferenceDir); + bindCurrentFolder (dialog, options.lastProfilingReferenceDir); dialog.set_current_name (lastRefFilename); dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 863e88a46..640cca5a2 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -83,7 +83,6 @@ private: Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; MyFileChooserButton* ipDialog; - std::auto_ptr ipDialogPersister; Gtk::RadioButton::Group opts; Gtk::Button* saveRef; sigc::connection ipc; diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index eb655f424..ca667c4d9 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -289,7 +289,7 @@ void ProfilePanel::save_clicked (GdkEventButton* event) } Gtk::FileChooserDialog dialog(M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); - FileChooserLastFolderPersister persister( &dialog, options.loadSaveProfilePath ); + bindCurrentFolder (dialog, options.loadSaveProfilePath); dialog.set_current_name (lastFilename); //Add the user's default (or global if multiuser=false) profile path to the Shortcut list @@ -465,7 +465,7 @@ void ProfilePanel::load_clicked (GdkEventButton* event) } Gtk::FileChooserDialog dialog(M("PROFILEPANEL_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN); - FileChooserLastFolderPersister persister( &dialog, options.loadSaveProfilePath ); + bindCurrentFolder (dialog, options.loadSaveProfilePath); //Add the user's default (or global if multiuser=false) profile path to the Shortcut list #ifdef WIN32 diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index e3428dea7..338c5b36e 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -94,21 +94,12 @@ RTWindow::RTWindow () Glib::ustring fName = "rt-logo.png"; Glib::ustring fullPath = RTImage::findIconAbsolutePath(fName); -#ifdef GLIBMM_EXCEPTIONS_ENABLED - try { set_default_icon_from_file (fullPath); } catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } -#else - { - std::auto_ptr error; - set_default_icon_from_file (fullPath, error); - } -#endif //GLIBMM_EXCEPTIONS_ENABLED - #if defined(__APPLE__) { osxApp = (GtkosxApplication *)g_object_new (GTKOSX_TYPE_APPLICATION, NULL);