Merge with 'Beep6581/dev'
This commit is contained in:
@@ -73,7 +73,10 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr)
|
||||
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);
|
||||
templateHelpButton = Gtk::manage (new Gtk::ToggleButton("?"));
|
||||
templateHelpButton->set_tooltip_markup (M ("QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP"));
|
||||
hb2->pack_start (*templateHelpButton, Gtk::PACK_SHRINK, 0);
|
||||
odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 0);
|
||||
outdirTemplate->set_tooltip_markup (M("QUEUE_LOCATION_TEMPLATE_TOOLTIP"));
|
||||
useTemplate->set_tooltip_markup (M("QUEUE_LOCATION_TEMPLATE_TOOLTIP"));
|
||||
Gtk::Box* hb3 = Gtk::manage (new Gtk::Box ());
|
||||
@@ -108,6 +111,14 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr)
|
||||
#endif
|
||||
|
||||
odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4);
|
||||
destinationPreviewLabel = Gtk::manage (new Gtk::Label ());
|
||||
destinationPreviewLabel->set_tooltip_markup (M("QUEUE_DESTPREVIEW_TOOLTIP"));
|
||||
destinationPreviewLabel->set_selectable (true); // so users can copy the path to the clipboard
|
||||
destinationPreviewLabel->set_halign (Gtk::ALIGN_START);
|
||||
auto destinationPreviewScrolledWindow = Gtk::manage(new Gtk::ScrolledWindow ());
|
||||
destinationPreviewScrolledWindow->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
destinationPreviewScrolledWindow->add (*destinationPreviewLabel);
|
||||
odvb->pack_start (*destinationPreviewScrolledWindow, Gtk::PACK_SHRINK);
|
||||
Gtk::RadioButton::Group g = useTemplate->get_group();
|
||||
useFolder->set_group (g);
|
||||
fdir->add (*odvb);
|
||||
@@ -122,11 +133,13 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr)
|
||||
outdirTemplate->set_text (options.savePathTemplate);
|
||||
useTemplate->set_active (options.saveUsePathTemplate);
|
||||
useFolder->set_active (!options.saveUsePathTemplate);
|
||||
destinationPreviewLabel->set_text (M("QUEUE_DESTPREVIEW_TITLE"));
|
||||
|
||||
// setup signal handlers
|
||||
outdirTemplate->signal_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));
|
||||
templateHelpButton->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::templateHelpButtonToggled));
|
||||
saveFormatPanel->setListener (this);
|
||||
|
||||
// setup button bar
|
||||
@@ -138,8 +151,19 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr)
|
||||
topBox->pack_start (*fdir, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
topBox->pack_start (*fformat, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||
|
||||
middleSplitPane = Gtk::manage (new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL));
|
||||
templateHelpTextView = Gtk::manage (new Gtk::TextView());
|
||||
templateHelpTextView->set_editable(false);
|
||||
templateHelpTextView->set_wrap_mode(Gtk::WRAP_WORD);
|
||||
scrolledTemplateHelpWindow = Gtk::manage(new Gtk::ScrolledWindow());
|
||||
scrolledTemplateHelpWindow->add(*templateHelpTextView);
|
||||
middleSplitPane->pack1 (*scrolledTemplateHelpWindow);
|
||||
middleSplitPane->pack2 (*batchQueue);
|
||||
scrolledTemplateHelpWindow->set_visible(false); // initially hidden, templateHelpButton shows it
|
||||
scrolledTemplateHelpWindow->set_no_show_all(true);
|
||||
|
||||
// add middle browser area
|
||||
pack_start (*batchQueue);
|
||||
pack_start (*middleSplitPane);
|
||||
|
||||
// lower box with thumbnail zoom
|
||||
bottomBox = Gtk::manage (new Gtk::Box ());
|
||||
@@ -313,6 +337,122 @@ void BatchQueuePanel::setGuiFromBatchState(bool queueRunning, int qsize)
|
||||
updateTab(qsize);
|
||||
}
|
||||
|
||||
void BatchQueuePanel::templateHelpButtonToggled()
|
||||
{
|
||||
bool visible = templateHelpButton->get_active();
|
||||
auto buffer = templateHelpTextView->get_buffer();
|
||||
if (buffer->get_text().empty()) {
|
||||
// Populate the help text the first time it's shown
|
||||
populateTemplateHelpBuffer(buffer);
|
||||
const auto fullWidth = middleSplitPane->get_width();
|
||||
middleSplitPane->set_position(fullWidth / 2);
|
||||
}
|
||||
scrolledTemplateHelpWindow->set_visible(visible);
|
||||
templateHelpTextView->set_visible(visible);
|
||||
}
|
||||
|
||||
void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr<Gtk::TextBuffer> buffer)
|
||||
{
|
||||
auto pos = buffer->begin();
|
||||
const auto insertTopicHeading = [&pos, buffer](const Glib::ustring& text) {
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n<u><b>", text, "</b></u>\n"));
|
||||
};
|
||||
const auto insertTopicBody = [&pos, buffer](const Glib::ustring& text) {
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n", text, "\n"));
|
||||
};
|
||||
const auto mainTitle = M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE");
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("<big><b>", mainTitle, "</b></big>\n"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO"));
|
||||
|
||||
insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY"));
|
||||
|
||||
insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO"));
|
||||
pos = buffer->insert(pos, "\n");
|
||||
#ifdef _WIN32
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS"));
|
||||
pos = buffer->insert(pos, "\n");
|
||||
#endif
|
||||
pos = buffer->insert(pos, "\n");
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1"));
|
||||
#ifdef _WIN32
|
||||
const auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS");
|
||||
#else
|
||||
const auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX");
|
||||
#endif
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2"));
|
||||
// Examples are generated from exampleFilePath using the actual template processing function
|
||||
const Options savedOptions = options; // to be restored after generating example results
|
||||
options.saveUsePathTemplate = true;
|
||||
// Since this code only ever runs once (the first time the help text is presented), no attempt is
|
||||
// made to be efficient. Use a brute-force method to discover the number of elements in exampleFilePath.
|
||||
int pathElementCount = 0;
|
||||
for (int n=9; n>=0; n--) {
|
||||
options.savePathTemplate = Glib::ustring::format("%d", n);
|
||||
const auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath);
|
||||
if (!result.empty()) {
|
||||
// The 'd' specifier returns an empty string if N exceeds the number of path elements, so
|
||||
// the largest N that does not return an empty string is the number of elements in exampleFilePath.
|
||||
pathElementCount = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Function inserts examples for a particular specifier, with every valid N value for the
|
||||
// number of elements in the path.
|
||||
const auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2)
|
||||
{
|
||||
for (int n=0; n<pathElementCount; n++) {
|
||||
auto path1 = Glib::ustring::format("%", letter, offset1+n*mult1);
|
||||
auto path2 = Glib::ustring::format("%", letter, offset2+n*mult2);
|
||||
options.savePathTemplate = path1;
|
||||
auto result1 = BatchQueue::calcAutoFileNameBase(exampleFilePath);
|
||||
options.savePathTemplate = path2;
|
||||
auto result2 = BatchQueue::calcAutoFileNameBase(exampleFilePath);
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n <tt><b>", path1, "</b> = <b>", path2, "</b> = <i>", result1, "</i></tt>"));
|
||||
if (result1 != result2) {
|
||||
// If this error appears, it indicates a coding error in either BatchQueue::calcAutoFileNameBase
|
||||
// or BatchQueuePanel::populateTemplateHelpBuffer.
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2));
|
||||
}
|
||||
}
|
||||
};
|
||||
// Example outputs in comments below are for a 4-element path.
|
||||
insertPathExamples('d', pathElementCount, -1, -1, -1); // <b>%d4</b> = <b>%d-1</b> = <i>home</i>
|
||||
insertPathExamples('p', 1, 1, -pathElementCount, 1); // <b>%p1</b> = <b>%p-4</b> = <i>/home/tom/photos/2010-10-31/</i>
|
||||
insertPathExamples('P', 1, 1, -pathElementCount, 1); // <b>%P1</b> = <b>%P-4</b> = <i>2010-10-31/</i>
|
||||
{
|
||||
const Glib::ustring fspecifier("%f");
|
||||
options.savePathTemplate = fspecifier;
|
||||
const auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath);
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n <tt><b>", fspecifier, "</b> = <i>", result, "</i></tt>"));
|
||||
}
|
||||
|
||||
insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY"));
|
||||
|
||||
insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY"));
|
||||
|
||||
insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE"));
|
||||
pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY"));
|
||||
const Glib::ustring dateTimeFormatExamples[] = {
|
||||
"%Y-%m-%d",
|
||||
"%Y%m%d_%H%M%S",
|
||||
"%y/%b/%-d/"
|
||||
};
|
||||
const auto timezone = Glib::DateTime::create_now_local().get_timezone();
|
||||
const auto timeForExamples = Glib::DateTime::create_from_iso8601("2001-02-03T04:05:06.123456", timezone);
|
||||
for (auto && fmt : dateTimeFormatExamples) {
|
||||
const auto result = timeForExamples.format(fmt);
|
||||
pos = buffer->insert_markup(pos, Glib::ustring::format("\n <tt><b>%tE\"", fmt, "\"</b> = <i>", result, "</i></tt>"));
|
||||
}
|
||||
|
||||
pos = buffer->insert(pos, "\n");
|
||||
options = savedOptions; // Do not add any lines in this function below here
|
||||
}
|
||||
|
||||
void BatchQueuePanel::addBatchQueueJobs(const std::vector<BatchQueueEntry*>& entries, bool head)
|
||||
{
|
||||
batchQueue->addEntries(entries, head);
|
||||
@@ -329,6 +469,7 @@ void BatchQueuePanel::saveOptions ()
|
||||
options.savePathTemplate = outdirTemplate->get_text();
|
||||
options.saveUsePathTemplate = useTemplate->get_active();
|
||||
options.procQueueEnabled = qAutoStart->get_active();
|
||||
batchQueue->updateDestinationPathPreview();
|
||||
}
|
||||
|
||||
bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event)
|
||||
@@ -358,6 +499,11 @@ bool BatchQueuePanel::canStartNext ()
|
||||
return queueShouldRun;
|
||||
}
|
||||
|
||||
void BatchQueuePanel::setDestinationPreviewText(const Glib::ustring &destinationPath)
|
||||
{
|
||||
destinationPreviewLabel->set_text(destinationPath);
|
||||
}
|
||||
|
||||
void BatchQueuePanel::pathFolderButtonPressed ()
|
||||
{
|
||||
|
||||
@@ -381,9 +527,11 @@ void BatchQueuePanel::pathFolderButtonPressed ()
|
||||
void BatchQueuePanel::pathFolderChanged ()
|
||||
{
|
||||
options.savePathFolder = outdirFolder->get_filename();
|
||||
batchQueue->updateDestinationPathPreview();
|
||||
}
|
||||
|
||||
void BatchQueuePanel::formatChanged(const Glib::ustring& format)
|
||||
{
|
||||
options.saveFormatBatch = saveFormatPanel->getFormat();
|
||||
batchQueue->updateDestinationPathPreview();
|
||||
}
|
||||
|
Reference in New Issue
Block a user