Commit ab955a0a authored by Dirk Wilden's avatar Dirk Wilden

saving multiple objects into one file

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@8969 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 9cefa9dd
......@@ -179,6 +179,14 @@ public slots:
*/
virtual bool saveObject(int /*_id*/, QString /*_filename*/) = 0;
/** \brief Save multiple objects to one file
*
* The Core will call this slot if the user wants to save multiple files in one file.
* The core will check if you support the given object depending on the
* provided dataTypes ( see supportedType ).
* Additionally to the filename you get ids of the objects to save
*/
virtual bool saveObjects(IdList /*_ids*/, QString /*_filename*/){return false;};
/** @} */
};
......
......@@ -120,6 +120,7 @@ struct fileTypes {
QString saveFilters;
FileInterface* plugin;
QObject* object;
bool saveMultipleObjects;
};
struct dataTypes {
......@@ -614,6 +615,8 @@ private slots:
bool saveObject( int _id, QString _filename );
void saveObject( int _id, QString _filename, int _pluginID );
void saveObjects( IdList _ids, QString _filename, int _pluginID );
/** Show dialog for saving an object to a new location
* @param _id id of the object
......@@ -621,6 +624,8 @@ private slots:
*/
bool saveObjectTo( int _id, QString _filename );
bool saveObjectsTo( IdList _ids, QString _filename );
/// Slot for saving objects from Menu
void saveAllObjects();
......
......@@ -1322,6 +1322,7 @@ void Core::loadPlugin(QString filename, bool silent, QObject* _plugin){
ft.saveFilters = filePlugin->getSaveFilters();
ft.plugin = filePlugin;
ft.object = plugin;
ft.saveMultipleObjects = checkSlot(plugin,"saveObjects(IdList,QString)");
supportedTypes_.push_back(ft);
}
......
......@@ -135,6 +135,53 @@ void Core::saveObject( int _id, QString _filename, int _pluginID ) {
//-----------------------------------------------------------------------------------------------------
/// Save multiple objects to one file
/// get object with given id, find a plugin to save dataType, save!
/// (existing files will be overwritten)
void Core::saveObjects( IdList _ids, QString _filename, int _pluginID ) {
DataType type = 0;
for (uint i=0; i < _ids.size(); i++){
BaseObjectData* object;
PluginFunctions::getObject(_ids[i],object);
type |= object->dataType();
}
if ( OpenFlipper::Options::gui() ) {
coreWidget_->statusMessage( tr("Saving ") + _filename + " ...");
if ( !OpenFlipper::Options::savingSettings() )
coreWidget_->setStatus(ApplicationStatus::PROCESSING );
}
//save objects
if ( !supportedTypes_[_pluginID].saveMultipleObjects){
emit log(LOGERR, tr("Unable to save objects. Plugin does not allow multiple objects."));
return;
}
bool ok = supportedTypes_[_pluginID].plugin->saveObjects(_ids,_filename);
if ( OpenFlipper::Options::gui() ) {
if (ok)
coreWidget_->statusMessage( tr("Saving ") + _filename + tr(" ... done"), 4000 );
else
coreWidget_->statusMessage( tr("Saving ") + _filename + tr(" ... failed!"), 4000 );
if ( !OpenFlipper::Options::savingSettings() )
coreWidget_->setStatus(ApplicationStatus::READY );
}
//add to recent files
if (ok && !OpenFlipper::Options::savingSettings()
&& OpenFlipper::Options::gui() )
coreWidget_->addRecent( _filename, type );
}
//-----------------------------------------------------------------------------------------------------
/// Save an object to a new location
/// Show the save-widget to determine a filename, the widget calls slotSave to save the object
bool Core::saveObjectTo( int _id, QString _filename ) {
......@@ -142,15 +189,11 @@ bool Core::saveObjectTo( int _id, QString _filename ) {
bool result = false;
if ( OpenFlipper::Options::gui() ){
BaseObjectData* object;
PluginFunctions::getObject(_id,object);
//init widget
LoadWidget* widget = new LoadWidget(supportedTypes_);
widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
connect(widget,SIGNAL(load(QString, int)),this,SLOT(slotLoad(QString, int)));
connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
if (supportedTypes_.size() != 0)
......@@ -167,6 +210,34 @@ bool Core::saveObjectTo( int _id, QString _filename ) {
//-----------------------------------------------------------------------------------------------------
/// Save multiple objects to a new location
/// Show the save-widget to determine a filename, the widget calls slotSave to save the objects
bool Core::saveObjectsTo( IdList _ids, QString _filename ) {
bool result = false;
if ( OpenFlipper::Options::gui() ){
//init widget
LoadWidget* widget = new LoadWidget(supportedTypes_);
widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
connect(widget,SIGNAL(save(IdList, QString, int)),this,SLOT(saveObjects(IdList, QString, int)));
if (supportedTypes_.size() != 0)
result = widget->showSave(_ids,_filename);
else
emit log(LOGERR,tr("Could not show 'save objects' dialog. Missing file-plugins."));
widget->disconnect();
delete widget;
}
return result;
}
//-----------------------------------------------------------------------------------------------------
/// Save changes for all target objects (slot is called from CoreWidget's File-Menu)
void Core::saveAllObjects(){
......@@ -195,16 +266,45 @@ void Core::saveAllObjects(){
/// Save all target objects under new name (slot is called from CoreWidget's File-Menu)
void Core::saveAllObjectsTo(){
if ( OpenFlipper::Options::gui() ){
if (supportedTypes_.size() != 0){
//ensure that all options are on their default values
for (int i=0; i < (int)supportedTypes_.size(); i++)
supportedTypes_[i].plugin->saveOptionsWidget("");
//get all dataTypes that want to be saved
DataType types = DATA_UNKNOWN;
IdList ids;
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ;
o_it != PluginFunctions::objectsEnd(); ++o_it){
types |= o_it->dataType();
ids.push_back( o_it->id() );
}
//check if a plugin can save all types to one file
bool multiSave = false;
for (int i=0; i < (int)supportedTypes_.size(); i++)
if ( (supportedTypes_[i].saveMultipleObjects) && (supportedTypes_[i].type.contains(types)) )
multiSave = true;
if (ids.size() > 1 && multiSave){
//save all objets to one file and use name of first object
PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS);
saveObjectsTo(ids,o_it->name());
} else {
//save each object separately
//iterate over all target objects
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS);
o_it != PluginFunctions::objectsEnd(); ++o_it) {
QString filename = o_it->path() + OpenFlipper::Options::dirSeparator() + o_it->name();
saveObjectTo(o_it->id(),filename);
}
}else
emit log(LOGERR,tr("Could not show 'save objects' dialog. Missing file-plugins."));
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS) ;
o_it != PluginFunctions::objectsEnd(); ++o_it)
saveObjectTo(o_it->id(),o_it->name());
}
}
}
......
......@@ -107,7 +107,11 @@ class DLLEXPORT DataType {
bool operator&( const unsigned int& _i );
bool operator&( const DataType& _i ) const;
DataType operator!();
bool contains( const DataType& _i );
DataType operator|( const DataType& _i ) const;
bool operator++(int _unused);
......
......@@ -149,6 +149,11 @@ void initializeTypes() {
/// Adds a datatype and returns the id for the new type
DataType addDataType(QString _name, QString _readableName) {
if ( typeId(_name) != DATA_UNKNOWN ) {
std::cerr << "Redefinition of existing data type!" << std::endl;
return typeId(_name);
}
int type = nextTypeId_;
stringToTypeInfo[ _name ] = types.size();
......@@ -370,6 +375,21 @@ bool DataType::operator&( const DataType& _i ) const {
//===========================================
DataType DataType::operator!() {
DataType inv = (*this);
inv.field = !inv.field;
return inv;
}
//===========================================
bool DataType::contains( const DataType& _i ){
//its not magic
return ( (_i.field & field) == _i.field);
}
//===========================================
DataType& DataType::operator|=( const unsigned int& _i ) {
field |= _i;
return (*this);
......
......@@ -156,18 +156,18 @@ void CoreWidget::setupMenuBar()
fileMenu_->addSeparator();
//Save object
QAction* AC_Save = new QAction(tr("Save Object"), this);
QAction* AC_Save = new QAction(tr("Save Objects"), this);
// AC_Save->setShortcut (Qt::CTRL + Qt::Key_S);
AC_Save->setStatusTip(tr("Save currently selected objects"));
AC_Save->setWhatsThis(tr("Saves all currently selected objects"));
AC_Save->setStatusTip(tr("Save current objects"));
AC_Save->setWhatsThis(tr("Save current objects"));
AC_Save->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"document-save.png"));
connect(AC_Save, SIGNAL(triggered()), this, SIGNAL(saveMenu()));
fileMenu_->addAction(AC_Save);
//Save object to
QAction* AC_Save_to = new QAction(tr("Save Object To"), this);
AC_Save_to->setStatusTip(tr("Save current Object(s) To"));
AC_Save_to->setWhatsThis(tr("Saves all currently selected objects under a new name"));
QAction* AC_Save_to = new QAction(tr("Save Objects to"), this);
AC_Save_to->setStatusTip(tr("Save current Object(s) to"));
AC_Save_to->setWhatsThis(tr("Save current Object(s) under a new name"));
AC_Save_to->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"document-save-as.png"));
connect(AC_Save_to, SIGNAL(triggered()), this, SIGNAL(saveToMenu()));
fileMenu_->addAction(AC_Save_to);
......
......@@ -144,8 +144,14 @@ void LoadWidget::slotSetSaveFilters(DataType _type){
QStringList allFilters;
bool multipleFiles = (ids_.size() > 1);
for (int i=0; i < (int)supportedTypes_.size(); i++)
if (supportedTypes_[i].type & _type){
if ( supportedTypes_[i].type.contains(_type) ){
if ( multipleFiles && !supportedTypes_[i].saveMultipleObjects)
continue;
QStringList filters = supportedTypes_[i].saveFilters.split(";;");
for (int f=filters.size()-1; f >= 0; f--){
if (filters[f].trimmed() == "") { filters.removeAt(f); continue; }
......@@ -280,7 +286,7 @@ void LoadWidget::saveFile(){
for (uint t=0; t < supportedTypes_.size(); t++){
QString filters = supportedTypes_[t].loadFilters;
QString filters = supportedTypes_[t].saveFilters;
if (filters.contains( fi.suffix() )){
pluginForExtension_[ fi.suffix() ] = t;
......@@ -308,8 +314,12 @@ void LoadWidget::saveFile(){
return; //abort if users doesn't want to overwrite
}
if ( pluginForExtension_.find( fi.suffix() ) != pluginForExtension_.end() )
emit save(id_,filename, pluginForExtension_[fi.suffix()] );
if ( pluginForExtension_.find( fi.suffix() ) != pluginForExtension_.end() ){
if (ids_.size() == 1)
emit save(ids_[0],filename, pluginForExtension_[fi.suffix()] );
else
emit save(ids_ ,filename, pluginForExtension_[fi.suffix()] );
}
OpenFlipperSettings().setValue("Core/CurrentDir", fi.absolutePath() );
}
......@@ -329,12 +339,16 @@ int LoadWidget::showLoad(){
/// show Widget for saving Files
int LoadWidget::showSave(int _id, QString _filename){
std::cerr << "save single file" << std::endl;
setAcceptMode ( QFileDialog::AcceptSave );
setFileMode( QFileDialog::AnyFile );
setWindowTitle(tr("Save Object"));
loadMode_ = false;
id_ = _id;
ids_.clear();
ids_.push_back(_id);
//set dataType
BaseObjectData* object;
......@@ -388,6 +402,76 @@ int LoadWidget::showSave(int _id, QString _filename){
return this->exec();
}
/// show Widget for saving Files
int LoadWidget::showSave(IdList _ids, QString _filename){
std::cerr << "save multiple files" << std::endl;
setAcceptMode ( QFileDialog::AcceptSave );
setFileMode( QFileDialog::AnyFile );
setWindowTitle(tr("Save Objects"));
loadMode_ = false;
ids_ = _ids;
DataType types = 0;
for (uint i=0; i < _ids.size(); i++){
BaseObjectData* object;
PluginFunctions::getObject(_ids[i], object);
types |= object->dataType();
}
//check if we can save this dataType
bool typeFound = false;
for (int i=0; i < (int)supportedTypes_.size(); i++)
if ( supportedTypes_[i].type.contains(types) )
typeFound = true;
if (!typeFound){
std::cerr << "No suitable plugin for saving this dataType." << std::endl;
return QDialog::Rejected;
}
slotSetSaveFilters( types );
//display correct path/name
QFileInfo fi(_filename);
QFile file(_filename);
if (file.exists()) {
setDirectory( fi.absolutePath() );
selectFile ( fi.fileName() );
} else {
// setDirectory(OpenFlipper::Options::currentDir().absolutePath() );
std::cout << "setting filename = " << _filename.toStdString() << std::endl;
setDirectory( fi.absolutePath() );
selectFile ( fi.fileName() );
}
//try to select the best fitting name filter
for (int i=0; i < nameFilters().count(); i++){
int s = nameFilters()[i].indexOf("*")+2;
int e = nameFilters()[i].indexOf(" ", s);
int e2 = nameFilters()[i].indexOf(")", s);
if (e == -1 || e2 < e) e = e2;
QString ext = nameFilters()[i].mid(s,e-s);
if (ext == fi.completeSuffix()){
selectNameFilter(nameFilters()[i]);
break;
}
}
return this->exec();
}
void LoadWidget::accept() {
if ( loadMode_ )
loadFile();
......
......@@ -59,7 +59,8 @@ class LoadWidget : public QFileDialog
signals:
void load(QString _filename, int _pluginID);
void save(int _id, QString _filename, int _pluginID);
void save(int _id, QString _filename, int _pluginID);
void save(IdList _ids, QString _filename, int _pluginID);
private slots:
void slotSetPluginForExtension(QString _extension, int _pluginId );
......@@ -67,7 +68,8 @@ class LoadWidget : public QFileDialog
void slotSetSaveFilters(DataType _type);
private:
int id_;
IdList ids_;
bool loadMode_;
QStringList lastPaths;
std::vector<fileTypes>& supportedTypes_;
......@@ -76,7 +78,8 @@ class LoadWidget : public QFileDialog
public:
int showLoad();
int showSave(int _id, QString _filename);
int showSave(int _id, QString _filename);
int showSave(IdList _ids, QString _filename);
public slots :
virtual void accept();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment