/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001-2007 by Diether Knof and Borg Enders * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Settings as * published by the Free Software Foundation; either version 2 of * the Settings, or (at your option) any later version. * * This program 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 Settings for more details. * You can find this license in the file 'gpl.txt'. * * You should have received a copy of the GNU General Public Settings * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@gmx.de * Borg Enders borg@borgsoft.de * *********************************************************************/ #include "constants.h" #ifdef USE_UI_GTKMM #include "filemenu.h" #include #include namespace Gtk { /** ** Constructor ** ** @param signal_slot the slot for the change signal ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ FileMenu::FileMenu(sigc::slot1 signal_slot) : Menu(), directories_(), signal_slot_(signal_slot) { this->realize(); this->signal_show().connect(sigc::mem_fun(*this, &FileMenu::update)); return ; } // FileMenu::FileMenu(sigc::slot1 signal_slot) /** ** Constructor ** ** @param signal_slot the slot for the change signal ** @param directory the directory to search from ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ FileMenu::FileMenu(sigc::slot1 signal_slot, string const& directory) : Menu(), directories_(1, directory), signal_slot_(signal_slot) { this->realize(); this->signal_show().connect(sigc::mem_fun(*this, &FileMenu::update)); return ; } // FileMenu::FileMenu(sigc::slot1 signal_slot, string const& directory) /** ** Constructor ** ** @param signal_slot the slot for the change signal ** @param directories the directories to search from ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ FileMenu::FileMenu(sigc::slot1 signal_slot, vector const& directories) : Menu(), directories_(directories), signal_slot_(signal_slot) { this->realize(); this->signal_show().connect(sigc::mem_fun(*this, &FileMenu::update)); return ; } // FileMenu::FileMenu(sigc::slot1 signal_slot, vector const& directories) /** ** Destruktor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ FileMenu::~FileMenu() { return ; } // FileMenu::~FileMenu() /** ** sets the directory ** ** @param directory new directory ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ void FileMenu::set_directory(string const& directory) { this->directories_.clear(); this->add_directory(directory); return ; } // void FileMenu::set_directory(string const& directory) /** ** add the directory to the list ** ** @param directory new directory ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ void FileMenu::add_directory(string const& directory) { this->directories_.push_back(directory); //this->update(); return ; } // void FileMenu::add_directory(string const& directory) /** ** sets the directories ** ** @param directories new directories ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ void FileMenu::set_directories(vector const& directories) { this->directories_ = directories; return ; } // void FileMenu::set_directories(vector const& directories) /** ** sets the signal slot ** ** @param signal_slot the signal slot ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ void FileMenu::set_signal_slot(sigc::slot1 signal_slot) { this->signal_slot_ = signal_slot; return ; } // void FileMenu::set_signal_slot(sigc::slot1 signal_slot) /** ** shows the menu ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 **/ void FileMenu::show() { this->popup(0, 0); this->update(); return ; } // void FileMenu::show() /** ** updates the menu (recreates it) ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 ** ** @todo transform the filename into utf8 **/ void FileMenu::update() { { // remove all childs Glib::ListHandle children = this->get_children(); for (Glib::ListHandle::iterator child = children.begin(); child != children.end(); child++) this->remove(**child); } // remove all childs this->add(*(Gtk::manage(new Gtk::TearoffMenuItem()))); this->show_all(); string* const subdirname = static_cast(this->get_data("subdirname")); bool first_directory = true; for (vector::const_iterator directory = this->directories_.begin(); directory != this->directories_.end(); directory++) { if (!Glib::file_test(*directory, Glib::FILE_TEST_EXISTS)) continue; if (!first_directory) this->add(*(Gtk::manage(new Gtk::SeparatorMenuItem()))); else first_directory = false; Glib::Dir dir(*directory); for (Glib::DirIterator filename = dir.begin(); filename != dir.end(); ++filename) { #ifndef RELEASE if (*filename == ".svn") continue; #endif Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem(*filename)); if (this->accept(*directory + "/" + *filename)) { dynamic_cast(item->get_child())->set_text(this->item_label((subdirname ? *subdirname : ""), *filename)); if (subdirname) item->signal_activate().connect(sigc::bind(this->signal_slot_, *subdirname + "/" + *filename)); else item->signal_activate().connect(sigc::bind(this->signal_slot_, *filename)); this->add(*item); } else { // if !(this->accept(*directory + "/" + *filename)) if (Glib::file_test(*directory + "/" + *filename, Glib::FILE_TEST_IS_DIR)) { #if 0 FileMenu* subdir = Gtk::manage(new FileMenu(this->signal_slot_, *directory + "/" + *filename)); #endif FileMenu* subdir = Gtk::manage(this->create_new(*directory + "/" + *filename)); if (subdirname) subdir->set_data("subdirname", new string(*subdirname + "/" + *filename)); else subdir->set_data("subdirname", new string(*filename)); item->set_submenu(*subdir); this->add(*item); //item->show(); } // if (Glib::file_test(*directory + "/" + *filename, Glib::FILE_TEST_IS_DIR)) } // if !(this->accept(*directory + "/" + *filename)) } // for (filename \in dir) dir.close(); } // for (directory \in this->directories_) if (this->get_children().size() == 1) { this->remove(**(this->get_children().begin())); // The only child is the tearoff menu item. // Since only a tearoff menu item does not look good, // remove the tearoff item and add a stop image. Gtk::MenuItem* stop = Gtk::manage(new Gtk::MenuItem(*Gtk::manage(new Gtk::Image(Gtk::Stock::STOP, Gtk::ICON_SIZE_MENU)))); stop->set_sensitive(false); this->add(*stop); } // if (this->get_children().size() == 1) this->show_all(); Gtk::Main::iteration(false); return ; } // void FileMenu::update() /** ** -> result ** ** @param directory the directory ** ** @return a new file menu with the same settings ** ** @author Diether Knof ** ** @version 0.5.4 **/ FileMenu* FileMenu::create_new(string const directory) const { return (new FileMenu(this->signal_slot_, directory)); } // virtual bool FileMenu::create_new() const /** ** -> result ** ** @param filename filename to test ** ** @return whether the filename is accepted for the menu ** ** @author Diether Knof ** ** @version 0.5.4 **/ bool FileMenu::accept(string const filename) const { return Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR); } // virtual bool FileMenu::accept(string const filename) const /** ** -> result ** ** @param subdirname the name of the subdir ** @param filename the filename ** ** @return label of the menu item ** ** @author Diether Knof ** ** @version 0.5.4 **/ string FileMenu::item_label(string const subdirname, string const filename) const { return filename; } // virtual string FileMenu::item_label(string const subdirname, string const filename) const } // namespace Gtk #endif // #ifdef USE_UI_GTKMM