mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
more improvements
This commit is contained in:
parent
ce32c8c748
commit
0580d974ee
@ -94,69 +94,153 @@ generate_images(const Filename &archive_dir, TextMaker *text_maker) {
|
||||
int actual_index_height = thumb_y_space + num_rows * (thumb_height + thumb_caption_height + thumb_y_space);
|
||||
|
||||
PNMImage index_image;
|
||||
index_image.clear(actual_index_width, actual_index_height);
|
||||
index_image.fill(1.0, 1.0, 1.0);
|
||||
|
||||
Filename reduced_dir(archive_dir, "reduced/" + _dir->get_basename());
|
||||
|
||||
Photos::const_iterator pi;
|
||||
for (pi = _photos.begin(); pi != _photos.end(); ++pi) {
|
||||
const PhotoInfo &pinfo = (*pi);
|
||||
Photo *photo = _dir->get_photo(pinfo._photo_index);
|
||||
Filename photo_filename(_dir->get_dir(), photo->get_basename());
|
||||
nout << "Reading " << photo_filename << "\n";
|
||||
|
||||
PNMImage photo_image;
|
||||
if (!photo_image.read(photo_filename)) {
|
||||
nout << "Unable to read.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_full_x_size = photo_image.get_x_size();
|
||||
photo->_full_y_size = photo_image.get_y_size();
|
||||
|
||||
// Generate a reduced image for the photo.
|
||||
PNMImage reduced_image;
|
||||
compute_reduction(photo_image, reduced_image, reduced_width, reduced_height);
|
||||
reduced_image.quick_filter_from(photo_image);
|
||||
Filename reduced_filename(reduced_dir, photo->get_basename());
|
||||
reduced_filename.make_dir();
|
||||
nout << "Writing " << reduced_filename << "\n";
|
||||
if (!reduced_image.write(reduced_filename)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_reduced_x_size = reduced_image.get_x_size();
|
||||
photo->_reduced_y_size = reduced_image.get_y_size();
|
||||
|
||||
// Generate a thumbnail image for the photo.
|
||||
PNMImage thumbnail_image;
|
||||
compute_reduction(reduced_image, thumbnail_image, thumb_width, thumb_height);
|
||||
|
||||
thumbnail_image.quick_filter_from(reduced_image);
|
||||
// Center the thumbnail image within its box.
|
||||
int x_center = (thumb_width - thumbnail_image.get_x_size()) / 2;
|
||||
int y_center = (thumb_height - thumbnail_image.get_y_size()) / 2;
|
||||
|
||||
index_image.copy_sub_image(thumbnail_image,
|
||||
pinfo._x_place + x_center,
|
||||
pinfo._y_place + y_center);
|
||||
|
||||
if (text_maker != (TextMaker *)NULL) {
|
||||
text_maker->generate_into(photo->get_name(), index_image,
|
||||
pinfo._x_place + thumb_width / 2,
|
||||
pinfo._y_place + thumb_height + thumb_caption_height);
|
||||
}
|
||||
}
|
||||
|
||||
Filename output_filename(archive_dir, _name);
|
||||
output_filename.set_extension("jpg");
|
||||
|
||||
nout << "Writing " << output_filename << "\n";
|
||||
if (!index_image.write(output_filename)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
Photos::const_iterator pi;
|
||||
|
||||
// First, scan the image files to see if we can avoid regenerating
|
||||
// the index image.
|
||||
bool generate_index_image = true;
|
||||
if (!force_regenerate && output_filename.exists()) {
|
||||
// Maybe we don't need to renegerated the index.
|
||||
generate_index_image = false;
|
||||
|
||||
const Filename &newest_contributing_filename =
|
||||
_dir->get_newest_contributing_filename();
|
||||
if (!newest_contributing_filename.empty()) {
|
||||
generate_index_image =
|
||||
(output_filename.compare_timestamps(newest_contributing_filename) < 0);
|
||||
}
|
||||
|
||||
for (pi = _photos.begin();
|
||||
pi != _photos.end() && !generate_index_image;
|
||||
++pi) {
|
||||
const PhotoInfo &pinfo = (*pi);
|
||||
Photo *photo = _dir->get_photo(pinfo._photo_index);
|
||||
Filename photo_filename(_dir->get_dir(), photo->get_basename());
|
||||
|
||||
// If any of the source photos are newer than the index image,
|
||||
// we must regenerate it.
|
||||
generate_index_image =
|
||||
(output_filename.compare_timestamps(photo_filename) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (generate_index_image) {
|
||||
index_image.clear(actual_index_width, actual_index_height);
|
||||
index_image.fill(1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// Now go back through and read whichever images are necessary, or
|
||||
// just read the headers if we can get away with it.
|
||||
for (pi = _photos.begin(); pi != _photos.end(); ++pi) {
|
||||
const PhotoInfo &pinfo = (*pi);
|
||||
Photo *photo = _dir->get_photo(pinfo._photo_index);
|
||||
Filename photo_filename(_dir->get_dir(), photo->get_basename());
|
||||
Filename reduced_filename(reduced_dir, photo->get_basename());
|
||||
PNMImage reduced_image;
|
||||
|
||||
if (force_regenerate ||
|
||||
reduced_filename.compare_timestamps(photo_filename) < 0) {
|
||||
// If the reduced filename does not exist or is older than the
|
||||
// source filename, we must read the complete source filename to
|
||||
// generate the reduced image.
|
||||
nout << "Reading " << photo_filename << "\n";
|
||||
|
||||
PNMImage photo_image;
|
||||
if (!photo_image.read(photo_filename)) {
|
||||
nout << "Unable to read.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_full_x_size = photo_image.get_x_size();
|
||||
photo->_full_y_size = photo_image.get_y_size();
|
||||
|
||||
// Generate a reduced image for the photo.
|
||||
compute_reduction(photo_image, reduced_image, reduced_width, reduced_height);
|
||||
reduced_image.quick_filter_from(photo_image);
|
||||
reduced_filename.make_dir();
|
||||
nout << "Writing " << reduced_filename << "\n";
|
||||
if (!reduced_image.write(reduced_filename)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_reduced_x_size = reduced_image.get_x_size();
|
||||
photo->_reduced_y_size = reduced_image.get_y_size();
|
||||
|
||||
} else {
|
||||
// If the reduced image already exists and is newer than the
|
||||
// source image, use it.
|
||||
|
||||
// We still read the image header to determine its size.
|
||||
PNMImageHeader photo_image;
|
||||
if (!photo_image.read_header(photo_filename)) {
|
||||
nout << "Unable to read " << photo_filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_full_x_size = photo_image.get_x_size();
|
||||
photo->_full_y_size = photo_image.get_y_size();
|
||||
|
||||
if (generate_index_image) {
|
||||
// Now read the reduced image from disk, so we can put it on
|
||||
// the index image.
|
||||
nout << "Reading " << reduced_filename << "\n";
|
||||
|
||||
if (!reduced_image.read(reduced_filename)) {
|
||||
nout << "Unable to read.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
photo->_reduced_x_size = reduced_image.get_x_size();
|
||||
photo->_reduced_y_size = reduced_image.get_y_size();
|
||||
|
||||
} else {
|
||||
// If we're not generating an index image, we don't even need
|
||||
// the reduced image--just scan its header to get its size.
|
||||
PNMImageHeader reduced_image;
|
||||
if (!reduced_image.read_header(reduced_filename)) {
|
||||
nout << "Unable to read " << reduced_filename << "\n";
|
||||
return false;
|
||||
}
|
||||
photo->_reduced_x_size = reduced_image.get_x_size();
|
||||
photo->_reduced_y_size = reduced_image.get_y_size();
|
||||
}
|
||||
}
|
||||
|
||||
if (generate_index_image) {
|
||||
// Generate a thumbnail image for the photo.
|
||||
PNMImage thumbnail_image;
|
||||
compute_reduction(reduced_image, thumbnail_image, thumb_width, thumb_height);
|
||||
|
||||
thumbnail_image.quick_filter_from(reduced_image);
|
||||
// Center the thumbnail image within its box.
|
||||
int x_center = (thumb_width - thumbnail_image.get_x_size()) / 2;
|
||||
int y_center = (thumb_height - thumbnail_image.get_y_size()) / 2;
|
||||
|
||||
index_image.copy_sub_image(thumbnail_image,
|
||||
pinfo._x_place + x_center,
|
||||
pinfo._y_place + y_center);
|
||||
|
||||
if (text_maker != (TextMaker *)NULL) {
|
||||
text_maker->generate_into(photo->get_name(), index_image,
|
||||
pinfo._x_place + thumb_width / 2,
|
||||
pinfo._y_place + thumb_height + thumb_caption_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (generate_index_image) {
|
||||
nout << "Writing " << output_filename << "\n";
|
||||
if (!index_image.write(output_filename)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_index_x_size = index_image.get_x_size();
|
||||
|
@ -37,6 +37,9 @@ Filename prev_icon;
|
||||
Filename next_icon;
|
||||
Filename up_icon;
|
||||
|
||||
bool force_regenerate = false;
|
||||
bool format_rose = false;
|
||||
|
||||
// Computed parameters
|
||||
int thumb_count_x;
|
||||
int thumb_count_y;
|
||||
|
@ -44,6 +44,9 @@ extern Filename prev_icon;
|
||||
extern Filename next_icon;
|
||||
extern Filename up_icon;
|
||||
|
||||
extern bool force_regenerate;
|
||||
extern bool format_rose;
|
||||
|
||||
void finalize_parameters();
|
||||
|
||||
// The following parameters are all computed based on the above.
|
||||
|
@ -41,7 +41,33 @@ Indexify() {
|
||||
"archives (typically JPEG files), and will generate a number of "
|
||||
"thumbnail images and a series of HTML pages to browse them. It is "
|
||||
"especially useful in preparation for burning the photo archives to "
|
||||
"CD.");
|
||||
"CD.\n\n"
|
||||
|
||||
"A number of directories is named on the command line; each "
|
||||
"directory must contain a number of image files, and all directories "
|
||||
"should be within the same parent directory. Each directory is "
|
||||
"considered a \"roll\", which may or may not correspond to a physical "
|
||||
"roll of film, and the photos within each directory are grouped "
|
||||
"correspondingly on the generated HTML pages.\n\n"
|
||||
|
||||
"If a file exists by the same name as an image file but with the "
|
||||
"extension \"cm\", that file is taken to be a HTML comment about that "
|
||||
"particular image and is inserted the HTML page for that image. "
|
||||
"Similarly, if there is a file within a roll directory with the same "
|
||||
"name as the directory itself (but with the extension \"cm\"), that file "
|
||||
"is inserted into the front page to introduce that particular roll.\n\n"
|
||||
|
||||
"Normally, all image files with the specified extension (normally "
|
||||
"\"jpg\") within a roll directory are included in the index, and sorted "
|
||||
"into alphabetical (or numeric) order. If you wish to specify a "
|
||||
"different order, or use only a subset of the images in a directory, "
|
||||
"create a file in the roll directory with the same name as the "
|
||||
"directory itself, and the extension \"ls\". This file should "
|
||||
"simply list the filenames (with or without extension) within the "
|
||||
"roll directory in the order they should be listed. If the ls "
|
||||
"file exists but is empty, it indicates that the files should be "
|
||||
"listed in reverse order, as from a camera that loads its film "
|
||||
"upside-down.");
|
||||
|
||||
add_option
|
||||
("t", "title", 0,
|
||||
@ -63,6 +89,21 @@ Indexify() {
|
||||
"directories, from the directory named by -a.",
|
||||
&Indexify::dispatch_filename, NULL, &_roll_dir_root);
|
||||
|
||||
add_option
|
||||
("f", "", 0,
|
||||
"Forces the regeneration of all reduced and thumbnail images, even if "
|
||||
"image files already exist that seem to be newer than the source "
|
||||
"image files.",
|
||||
&Indexify::dispatch_none, &force_regenerate);
|
||||
|
||||
add_option
|
||||
("r", "", 0,
|
||||
"Specifies that roll directory names are encoded using the Rose "
|
||||
"convention of six digits: mmyyss, where mm and yy are the month and "
|
||||
"year, and ss is a sequence number of the roll within the month. This "
|
||||
"name will be reformatted to m-yy/s for output.",
|
||||
&Indexify::dispatch_none, &format_rose);
|
||||
|
||||
add_option
|
||||
("e", "extension", 0,
|
||||
"Specifies the filename extension (without a leading dot) to identify "
|
||||
@ -170,18 +211,23 @@ handle_args(ProgramBase::Args &args) {
|
||||
Filename filename = Filename::from_os_specific(*ai);
|
||||
filename.standardize();
|
||||
if (filename.is_directory()) {
|
||||
RollDirectory *roll_dir = new RollDirectory(filename);
|
||||
if (prev_roll_dir != (RollDirectory *)NULL) {
|
||||
roll_dir->_prev = prev_roll_dir;
|
||||
prev_roll_dir->_next = roll_dir;
|
||||
string basename = filename.get_basename();
|
||||
if (basename == "icons" || basename == "html" || basename == "reduced") {
|
||||
nout << "Ignoring " << filename << "; indexify-generated directory.\n";
|
||||
|
||||
} else {
|
||||
RollDirectory *roll_dir = new RollDirectory(filename);
|
||||
if (prev_roll_dir != (RollDirectory *)NULL) {
|
||||
roll_dir->_prev = prev_roll_dir;
|
||||
prev_roll_dir->_next = roll_dir;
|
||||
}
|
||||
|
||||
_roll_dirs.push_back(roll_dir);
|
||||
prev_roll_dir = roll_dir;
|
||||
}
|
||||
|
||||
_roll_dirs.push_back(roll_dir);
|
||||
prev_roll_dir = roll_dir;
|
||||
|
||||
} else if (filename.exists()) {
|
||||
nout << filename << " is not a directory name.\n";
|
||||
return false;
|
||||
nout << "Ignoring " << filename << "; not a directory.\n";
|
||||
|
||||
} else {
|
||||
nout << filename << " does not exist.\n";
|
||||
@ -225,9 +271,9 @@ post_command_line() {
|
||||
if (_front_title.empty()) {
|
||||
// Supply a default title.
|
||||
if (_roll_dirs.size() == 1) {
|
||||
_front_title = _roll_dirs.front()->get_basename();
|
||||
_front_title = _roll_dirs.front()->get_name();
|
||||
} else {
|
||||
_front_title = _roll_dirs.front()->get_basename() + " to " + _roll_dirs.back()->get_basename();
|
||||
_front_title = _roll_dirs.front()->get_name() + " to " + _roll_dirs.back()->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,41 +303,51 @@ post_command_line() {
|
||||
if (prev_icon.empty()) {
|
||||
prev_icon = Filename("icons", default_left_icon_filename);
|
||||
Filename icon_filename(_archive_dir, prev_icon);
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
if (force_regenerate || !icon_filename.exists()) {
|
||||
nout << "Generating " << icon_filename << "\n";
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
}
|
||||
output.write(default_left_icon, default_left_icon_size);
|
||||
}
|
||||
output.write(default_left_icon, default_left_icon_size);
|
||||
}
|
||||
if (next_icon.empty()) {
|
||||
next_icon = Filename("icons", default_right_icon_filename);
|
||||
Filename icon_filename(_archive_dir, next_icon);
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
if (force_regenerate || !icon_filename.exists()) {
|
||||
nout << "Generating " << icon_filename << "\n";
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
}
|
||||
output.write(default_right_icon, default_right_icon_size);
|
||||
}
|
||||
output.write(default_right_icon, default_right_icon_size);
|
||||
}
|
||||
if (up_icon.empty()) {
|
||||
up_icon = Filename("icons", default_up_icon_filename);
|
||||
Filename icon_filename(_archive_dir, up_icon);
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
if (force_regenerate || !icon_filename.exists()) {
|
||||
nout << "Generating " << icon_filename << "\n";
|
||||
icon_filename.make_dir();
|
||||
icon_filename.set_binary();
|
||||
|
||||
ofstream output;
|
||||
if (!icon_filename.open_write(output)) {
|
||||
nout << "Unable to write to " << icon_filename << "\n";
|
||||
exit(1);
|
||||
}
|
||||
output.write(default_up_icon, default_up_icon_size);
|
||||
}
|
||||
output.write(default_up_icon, default_up_icon_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,6 +395,7 @@ run() {
|
||||
// Then go back and generate the HTML.
|
||||
|
||||
Filename html_filename(_archive_dir, "index.htm");
|
||||
nout << "Generating " << html_filename << "\n";
|
||||
html_filename.set_text();
|
||||
ofstream root_html;
|
||||
if (!html_filename.open_write(root_html)) {
|
||||
|
@ -22,6 +22,10 @@
|
||||
#include "indent.h"
|
||||
#include "notify.h"
|
||||
#include "string_utils.h"
|
||||
#include "indexParameters.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::Constructor
|
||||
@ -33,6 +37,11 @@ RollDirectory(const Filename &dir) :
|
||||
_dir(dir)
|
||||
{
|
||||
_basename = _dir.get_basename();
|
||||
if (format_rose) {
|
||||
_name = format_basename(_basename);
|
||||
} else {
|
||||
_name = _basename;
|
||||
}
|
||||
_prev = (RollDirectory *)NULL;
|
||||
_next = (RollDirectory *)NULL;
|
||||
}
|
||||
@ -77,6 +86,21 @@ get_basename() const {
|
||||
return _basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::get_name
|
||||
// Access: Public
|
||||
// Description: Returns the formatted name of the directory. This is
|
||||
// often the same as the basename, but if -r is
|
||||
// specified on the command line it might be a somewhat
|
||||
// different, reformatted name. In any case, it is the
|
||||
// name of the roll as it should be presented to the
|
||||
// user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const string &RollDirectory::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::scan
|
||||
// Access: Public
|
||||
@ -84,17 +108,71 @@ get_basename() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool RollDirectory::
|
||||
scan(const string &extension) {
|
||||
vector_string contents;
|
||||
if (!_dir.scan_directory(contents)) {
|
||||
nout << "Could not read " << _dir << "\n";
|
||||
return false;
|
||||
bool reverse_order = false;
|
||||
bool explicit_list = false;
|
||||
|
||||
// Check for an .ls file in the roll directory, which may give an
|
||||
// explicit ordering, or if empty, it specifies reverse ordering.
|
||||
Filename ls_filename(_dir, _basename + ".ls");
|
||||
if (ls_filename.exists()) {
|
||||
add_contributing_filename(ls_filename);
|
||||
ls_filename.set_text();
|
||||
ifstream ls;
|
||||
if (!ls_filename.open_read(ls)) {
|
||||
nout << "Could not read " << ls_filename << "\n";
|
||||
} else {
|
||||
bool any_words = false;
|
||||
string word;
|
||||
ls >> word;
|
||||
while (!ls.eof() && !ls.fail()) {
|
||||
any_words = true;
|
||||
Filename try_filename(_dir, word);
|
||||
if (!try_filename.exists()) {
|
||||
try_filename = Filename(_dir, word + "." + extension);
|
||||
}
|
||||
if (!try_filename.exists()) {
|
||||
try_filename = Filename(_dir, _basename + word + "." + extension);
|
||||
}
|
||||
if (!try_filename.exists()) {
|
||||
try_filename = Filename(_dir, _basename + "0" + word + "." + extension);
|
||||
}
|
||||
if (try_filename.exists()) {
|
||||
_photos.push_back(new Photo(this, try_filename.get_basename()));
|
||||
} else {
|
||||
nout << "Frame " << word << " not found in " << _name << "\n";
|
||||
}
|
||||
ls >> word;
|
||||
}
|
||||
|
||||
if (!any_words) {
|
||||
// An empty .ls file just means reverse the order.
|
||||
reverse_order = true;
|
||||
} else {
|
||||
// A non-empty .ls file has listed all the files we need; no
|
||||
// need to scan the directory.
|
||||
explicit_list = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector_string::iterator ci;
|
||||
for (ci = contents.begin(); ci != contents.end(); ++ci) {
|
||||
Filename basename = (*ci);
|
||||
if (basename.get_extension() == extension) {
|
||||
_photos.push_back(new Photo(this, basename));
|
||||
if (!explicit_list) {
|
||||
vector_string contents;
|
||||
|
||||
if (!_dir.scan_directory(contents)) {
|
||||
nout << "Could not read " << _dir << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reverse_order) {
|
||||
reverse(contents.begin(), contents.end());
|
||||
}
|
||||
|
||||
vector_string::iterator ci;
|
||||
for (ci = contents.begin(); ci != contents.end(); ++ci) {
|
||||
Filename basename = (*ci);
|
||||
if (basename.get_extension() == extension) {
|
||||
_photos.push_back(new Photo(this, basename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +209,20 @@ collect_index_images() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::get_newest_contributing_filename
|
||||
// Access: Public
|
||||
// Description: Returns the Filename with the newest timestamp that
|
||||
// contributes to the contents of the index images in
|
||||
// this directory, if any (other than the images
|
||||
// themselves). This is used by the IndexImage code to
|
||||
// determine if it needs to regenerate the index image.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const Filename &RollDirectory::
|
||||
get_newest_contributing_filename() const {
|
||||
return _newest_contributing_filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::get_num_photos
|
||||
// Access: Public
|
||||
@ -218,9 +310,12 @@ generate_html(ostream &root_html, const Filename &archive_dir,
|
||||
|
||||
} else {
|
||||
root_html
|
||||
<< "<h2>" << _basename << "</h2>\n";
|
||||
<< "<h2>" << _name << "</h2>\n";
|
||||
}
|
||||
|
||||
nout << "Generating " << Filename(archive_dir, "html/")
|
||||
<< _basename << "/*\n";
|
||||
|
||||
IndexImages::iterator ii;
|
||||
for (ii = _index_images.begin(); ii != _index_images.end(); ++ii) {
|
||||
IndexImage *index_image = (*ii);
|
||||
@ -239,7 +334,7 @@ generate_html(ostream &root_html, const Filename &archive_dir,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RollDirectory::
|
||||
output(ostream &out) const {
|
||||
out << _basename;
|
||||
out << _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -300,6 +395,7 @@ insert_html_comment(ostream &html, Filename cm_filename) {
|
||||
}
|
||||
|
||||
// We didn't find it. Insert the whole file.
|
||||
cm.clear();
|
||||
cm.seekg(0);
|
||||
int ch = cm.get();
|
||||
while (ch != EOF) {
|
||||
@ -310,6 +406,20 @@ insert_html_comment(ostream &html, Filename cm_filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::add_contributing_filename
|
||||
// Access: Private
|
||||
// Description: Specifies an additional filename that contributes to
|
||||
// the index image.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RollDirectory::
|
||||
add_contributing_filename(const Filename &filename) {
|
||||
if (_newest_contributing_filename.empty() ||
|
||||
_newest_contributing_filename.compare_timestamps(filename) < 0) {
|
||||
_newest_contributing_filename = filename;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::insert_html_comment_body
|
||||
// Access: Private, Static
|
||||
@ -334,3 +444,36 @@ insert_html_comment_body(ostream &html, istream &cm) {
|
||||
// Reached end of file; good enough.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RollDirectory::format_basename
|
||||
// Access: Private, Static
|
||||
// Description: Reformats the roll directory into a user-friendly
|
||||
// name based on its encoded directory name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string RollDirectory::
|
||||
format_basename(const string &basename) {
|
||||
if (basename.length() <= 4) {
|
||||
return basename;
|
||||
}
|
||||
|
||||
// The first four characters must be digits.
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
if (!isdigit(basename[i])) {
|
||||
return basename;
|
||||
}
|
||||
}
|
||||
|
||||
string mm = basename.substr(0, 2);
|
||||
string yy = basename.substr(2, 2);
|
||||
string ss = basename.substr(4);
|
||||
|
||||
if (mm[0] == '0') {
|
||||
mm = mm[1];
|
||||
}
|
||||
while (ss.length() > 1 && ss[0] == '0') {
|
||||
ss = ss.substr(1);
|
||||
}
|
||||
|
||||
return mm + "-" + yy + "/" + ss;
|
||||
}
|
||||
|
@ -40,9 +40,12 @@ public:
|
||||
|
||||
const Filename &get_dir() const;
|
||||
const string &get_basename() const;
|
||||
const string &get_name() const;
|
||||
bool scan(const string &extension);
|
||||
void collect_index_images();
|
||||
|
||||
const Filename &get_newest_contributing_filename() const;
|
||||
|
||||
int get_num_photos() const;
|
||||
Photo *get_photo(int n) const;
|
||||
|
||||
@ -59,7 +62,9 @@ public:
|
||||
static bool insert_html_comment(ostream &html, Filename cm_filename);
|
||||
|
||||
private:
|
||||
void add_contributing_filename(const Filename &filename);
|
||||
static bool insert_html_comment_body(ostream &html, istream &cm);
|
||||
static string format_basename(const string &basename);
|
||||
|
||||
public:
|
||||
RollDirectory *_prev;
|
||||
@ -68,8 +73,11 @@ public:
|
||||
private:
|
||||
Filename _dir;
|
||||
string _basename;
|
||||
string _name;
|
||||
typedef pvector<Photo *> Photos;
|
||||
Photos _photos;
|
||||
|
||||
Filename _newest_contributing_filename;
|
||||
|
||||
typedef pvector<IndexImage *> IndexImages;
|
||||
IndexImages _index_images;
|
||||
|
Loading…
x
Reference in New Issue
Block a user