#include #include #include #include #include using namespace std; /////////////////////////////////////////////////////////////////////////// // Function prototypes void print_instructions(); /////////////////////////////////////////////////////////////////////////// // Image class definition // - Images are records about pictures taken and contain a name and a // string of tags. class Image{ friend ostream &operator<<(ostream &, Image); friend istream &operator>>(istream&, Image &); public: // Default constructor Image(); // Constructor with initial values Image(string, string); // Name observer string get_name(); // Tags observer string get_tags(); //Accesor for the tags. void set_tags(string); // Acessor for the name void set_name(string); //nextImage observer Image * get_next_image(); //nextImage accessor void set_next_image(Image *); // Image destructor ~Image(); private: string image_name; string image_tags; Image * nextImage; }; // Default constructor Image::Image(){ // MAKE THIS WORK } // Initializing Constructor // Initialize things nicely Image::Image(string initial_name, string initial_tags){ // MAKE THIS WORK } // Return the image name string Image::get_name(){ return image_name; } // Return the tags string Image::get_tags(){ return image_tags; } // Change the tags void Image::set_tags(string new_tags){ image_tags = new_tags; } // Change the name void Image::set_name(string new_name){ image_name = new_name; } //Find out what the next image is Image * Image::get_next_image(){ // MAKE THIS WORK } // Set the next image to what is passed as a parameter void Image::set_next_image(Image * new_image){ // MAKE THIS WORK } Image::~Image(){ // MAKE THIS WORK } ostream &operator<<(ostream & output, Image i){ output << i.image_name << " " << i.image_tags; }; istream &operator>>(istream& input, Image & i){ input >> i.image_name; input.ignore(); getline(input,i.image_tags); i.nextImage = NULL; }; // /////////////////////////////////////////////////////////////////////////// /* int main(){ // A small main program to test the image class // Create a new image Image test_image("DSCF0020","Bride, groom, close up"); // make sure the observors work cout << "Testing observors:" << endl; cout << "This should say DSCF0020: " << test_image.get_name() << endl; cout << "This should say 'Bride, groom, close up': " << test_image.get_tags() << endl; // make sure the accesor for the tags works: cout << "Testing accessors:" << endl; test_image.set_tags("Bride, groom, close up, pimple"); cout << "This should say 'Bride, groom, close up, pimple': " << test_image.get_tags() << endl; // make sure the friend functions work as well cout << "The next line should say 'DSCF0020 Bride, groom, close up, pimple':" << endl; cout << test_image << endl; // now test the input operator cout << "At the prompt, please type - D01 Bride, groom, family:" << endl; cin >> test_image; cout << "The next line should say 'D01 Bride, groom, family':" << endl; cout << test_image << endl; cout << test_image.get_tags() << endl; // Some new tests to make sure that the nextImage stuff works cout << "Testing pointer part" << endl << endl; Image * testPtr = new Image("DSC099.JPG","Grooms Father making a toast"); cout << " The next line should say: DSC099.JPG Grooms Father making a toast" << endl; cout << *testPtr << endl; Image * otherPtr = new Image("DSC100.JPG","Everyone toasting"); testPtr->set_next_image(otherPtr); cout << "The next line should say DSC100.JPG Everyone toasting" << endl; cout << * testPtr->get_next_image() << endl; } */ /////////////////////////////////////////////////////////////////////////// // Photo Set class // - A photo set is a collection of images. Each set has a name, and a vector // of images in it. class Photo_set{ public: // Default constructor for empty photo set Photo_set(); // Method that loads the Image names and tags from a file void load_set(string source_file); // Show a numbered list of images void display_images(); // return a copy of one of the images in the set Image extract_image(int); // Add an image to the set void add_image(Image); // Return the number of images int number_of_images(); // Return the name of the set string get_name(); // Set the name of the photo set void change_set_name(string); // Save the photo set into a file void save_set(string); // Destroy the photo set ~Photo_set(); private: string set_name; Image * images; // A small method to add a dynamically created image to the list // Here because we want to separate out operations that happen // in more than one method. void add_image_to_list(Image *); // A small method to delete the list // Again, used in different public methods. void clear_list(); }; // A default constructor that makes a blank set Photo_set::Photo_set(){ // MAKE THIS WORL } // A method that is given the name of a file and reads // the information from the file. // The file has the format: // One line with the set name // Many lines, each with one image on them // Clear the old list when loading a new one. // The private method clear_list is good for this void Photo_set::load_set(string filename){ // MAKE THIS WORK } // Display a numbered list of images contained in the photo set // Start with the name, so we know which set it is // Notice that numbering starts at 1, because we don't want to // confuse grandma void Photo_set::display_images(){ // MAKE THIS WORK } // Given an integer that represents a number from the display_images // list, return a copy of that image // It does not remove the extracted image from the list // I test to make sure the image number is in range; // if it isn't, the method prints an error message and exits. // if it is out of range it will crash anyway. There are better // ways of handling this, but they are more complicated than we care about Image Photo_set::extract_image(int image_number){ // MAKE THIS WORK } // Add an image to the set // This is tricky because we need to only add dynamically created // image objects; we can't add the parameter passed directly, as it is // goes out of scope when the method ends void Photo_set::add_image(Image new_image){ // MAKE THIS WORK } // Return the number of images // This is just the size of the vector int Photo_set::number_of_images(){ // MAKE THIS WORK } // Get name simply returns the name of the set string Photo_set::get_name(){ return set_name; } // Set the name of the photo set void Photo_set::change_set_name(string new_name){ set_name = new_name; } // Save the photo set into a file of the specified name // It should save the set name and all the images void Photo_set::save_set(string filename){ // MAKE THIS WORK } // This is a private function that will add a pointer to a file to the // image list. It needs to add to the end to keep the images ordered // If you add to the front, they will be reversed void Photo_set::add_image_to_list(Image * new_image){ // MAKE THIS WORK } // This is a private function that will clear the list and // set images to NULL void Photo_set::clear_list(){ // MAKE THIS WORK } // Destroy the photo set // For this we need to delete all the items on the list // since they live outside the object. If the object goes away without // deleting them, we get a memory leak. Photo_set::~Photo_set(){ // MAKE THIS WORK } /* /////////////////////////////////////////////////////////////////////////// // A main function to test that the photo_set class works // This is done is steps to test different parts of the program. int main(){ // This section is set up so you can add methods one or two at a time // and then just change where the return 0 happens. // It should be easier to work on and test a few things at a time // The first thing we test is the add_image method and the // display_images method. I used the private add_image_to_list // method in my add_image, so that gets tested too Photo_set test_set; Image test_image ("DSC901.JPG","Cows"); cout << "Adding image"; test_set.add_image(test_image); cout << endl << "Done" << endl << "The next line should read:" << "1 DSC901.JPG Cows"<< endl; test_set.display_images(); // Remove or comment out the line below when the above portion works return 0; // Now add some more images to better test the adding method and the printing // since adding can go wrong cout << "Adding image 2"; test_image.set_name("DSC902.JPG"); test_image.set_tags("Brown cows"); test_set.add_image(test_image); cout << ".....done" << endl << "Adding image 3"; test_image.set_name("DSC903.JPG"); test_image.set_tags("White cows"); test_set.add_image(test_image); cout << ".....done" << endl << "Adding image 4"; test_image.set_name("DSC904.JPG"); test_image.set_tags("Spotted cows"); test_set.add_image(test_image); cout << ".....done" << endl; cout << endl; cout << "There should be four cow pictures below, in order by name" << endl; test_set.display_images(); cout << endl; // Uncomment the line below until the above portion works // return 0; // Test the number_of_images method cout << "There should be 4 images, and there are: " << test_set.number_of_images() << endl; cout << endl; // Uncomment the line below until the above portion works // return 0; // test the extract image method // and the display again, to make sure it isn't removed Image result = test_set.extract_image(2); cout << "The next line should read: DSC902.JPG Brown cows" << endl; cout << result << endl; cout << endl; cout << "There should be four cow pictures below, in order by name" << endl; cout << "If there are fewer, extract removed from the list instead" << endl; cout << "returning a copy of the desired image." << endl; test_set.display_images(); cout << endl; // Uncomment the line below until the above portion works // return 0; // test the save_set // You can look at the file named "test-ouput" in pico to make sure that // it is correct. It should say "Cow collection" then the same four images // we saw before test_set.change_set_name("Cow collection"); test_set.save_set("test_output"); // Uncomment the line below until the above portion works // return 0; // Test the load_set // We should be able to load the set we just saved Photo_set another_set; another_set.load_set("test_output"); cout << "The set below should show our 4 cows" << endl; another_set.display_images(); cout << endl; // Uncomment the line below until the above portion works // return 0; // Load again to make sure the list is cleared another_set.load_set("test_output"); cout << "The set below should show our 4 cows. If there are more, " << "you forgot to clear the list before loading new things in." << endl; another_set.display_images(); cout << endl; cout << "If all these worked, the main from the last project should"; cout << "work now, without change." << endl; //return 0; } */ // Now for the real main This should display a menu and allow the user // to load a file into a photo set, move images from that photo set to // another, give the other a title, and save it to a file. int main(){ Photo_set file_set; Photo_set order; bool not_done = true; char choice; string filename; string set_save_name; int photo_number; Image temp_image; do { print_instructions(); cin >> choice; cin.ignore(); switch (choice){ case'L': case'l': cout << "Please enter the filename of the photo set to load: "; getline (cin, filename); file_set.load_set(filename); break; case'P': case'p': file_set.display_images(); cout << "Enter photo number would you like to add to your order: "; cin >> photo_number; if ( (photo_number < 1)|| (photo_number > file_set.number_of_images())){ cout << endl << "Image number out of range" << endl; break; } temp_image = file_set.extract_image(photo_number); order.add_image(temp_image); cout << endl << "Added " << temp_image.get_name() << " to order."<< endl; break; case 'D': case 'd': order.display_images(); break; case 'S': case 's': cout << "Enter filename for order save: "; getline (cin, filename); cout << "Enter the name of this order: "; getline (cin, set_save_name); order.change_set_name(set_save_name); order.save_set(filename); break; case 'Q': case 'q': not_done = false; cout << "Goodbye." << endl; break; default: cout << "Bad command option." << endl; }; }while (not_done); } void print_instructions(){ cout << endl << endl; cout << "Welcome to the PIC, Co. Photo chooser." << endl; cout << "This program will allow you to choose photos from one set" << endl; cout << "and add them to a second set which can them will be saved" << endl; cout << "so that it can be printed" << endl; cout << " " << endl; cout << "Menu choices:" << endl; cout << left; cout << setw(5) << "L" << setw(45) << "Load from a file into the main set" << endl; cout << setw(5) << "P" << setw(45) << "Pick a picture from the main set to add to the order" << endl; cout << setw(5) << "D" << setw(45) << "Display the photos currently in the order" << endl; cout << setw(5) << "S" << setw(45) << "Save the order for processing" << endl; cout << setw(5) << "Q" << setw(45) << "Quit the program" << endl; cout << endl << endl << "Your choice: "; }