Popup.cc 12.7 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  OpenFlipper is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16 17 18 19
//  OpenFlipper 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 Lesser General Public License for more details.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================




#include "DataControlPlugin.hh"

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>

Dirk Wilden's avatar
Dirk Wilden committed
40 41
#include <ACG/QtWidgets/QtMaterialDialog.hh>

Jan Möbius's avatar
 
Jan Möbius committed
42
#include <QInputDialog>
Dirk Wilden's avatar
Dirk Wilden committed
43
#include <QMessageBox>
44
#include "Menu.hh"
Jan Möbius's avatar
 
Jan Möbius committed
45

Dirk Wilden's avatar
Dirk Wilden committed
46
/// Slot for Remove action in ContextMenu
Jan Möbius's avatar
 
Jan Möbius committed
47 48
void DataControlPlugin::slotPopupRemove (  ) {
  QItemSelectionModel* selection = view_->selectionModel();
Dirk Wilden's avatar
Dirk Wilden committed
49 50

  if (selection == 0) return;
51

Jan Möbius's avatar
 
Jan Möbius committed
52
  // Get all selected rows
53 54
  QModelIndexList indexList = selection->selectedRows();

Dirk Wilden's avatar
Dirk Wilden committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

  QMessageBox msgBox;
  msgBox.setText("Do you really want to remove the selected objects?");
  msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  msgBox.setDefaultButton(QMessageBox::No);

  QString text;

  for ( int i = 0 ; i < indexList.size() ; ++i) {
    BaseObject* deleteItem = model_->getItem( indexList[i] );
    text += deleteItem->name() + "\n";
  }
  msgBox.setDetailedText(text);

  if ( msgBox.exec() == QMessageBox::No)
    return;

Jan Möbius's avatar
 
Jan Möbius committed
72
  for ( int i = 0 ; i < indexList.size() ; ++i) {
73

Jan Möbius's avatar
 
Jan Möbius committed
74
    BaseObject* deleteItem = model_->getItem( indexList[i] );
75

Jan Möbius's avatar
 
Jan Möbius committed
76 77 78
    // Skip the root item
    if ( model_->isRoot( deleteItem ) )
      continue;
79

Jan Möbius's avatar
 
Jan Möbius committed
80 81
    // remove the whole subtree below this item
    deleteItem->deleteSubtree();
82

Jan Möbius's avatar
 
Jan Möbius committed
83 84
    // remove the item itself from the parent
    deleteItem->parent()->removeChild(deleteItem);
85

Jan Möbius's avatar
 
Jan Möbius committed
86 87 88
    // delete it
    delete deleteItem;
  }
89

Jan Möbius's avatar
 
Jan Möbius committed
90 91
  emit updateView();
  emit updatedObject(-1);
Jan Möbius's avatar
 
Jan Möbius committed
92 93
}

Dirk Wilden's avatar
Dirk Wilden committed
94
/// Slot for Ungroup action in ContextMenu
Jan Möbius's avatar
 
Jan Möbius committed
95 96
void DataControlPlugin::slotUngroup (  ) {
  QItemSelectionModel* selection = view_->selectionModel();
97

Jan Möbius's avatar
 
Jan Möbius committed
98
  // Get all selected rows
99
  QModelIndexList indexList = selection->selectedRows ( 0 );
Jan Möbius's avatar
 
Jan Möbius committed
100 101 102 103 104 105 106 107 108 109 110 111 112

  //remove complete group if selected item was a group
  BaseObject* group = model_->getItem( indexList[0]);

  for (int i=0; i < group->childCount(); i++){
    group->child(i)->setParent(group->parent());
    group->parent()->appendChild( group->child(i) );
  }

  group->parent()->removeChild(group);

  delete group;

Jan Möbius's avatar
 
Jan Möbius committed
113
  emit updatedObject(-1);
Jan Möbius's avatar
 
Jan Möbius committed
114 115
}

Dirk Wilden's avatar
Dirk Wilden committed
116
/// Slot for Copy action in ContextMenu
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
void DataControlPlugin::slotCopy (  ) {
  QItemSelectionModel* selection = view_->selectionModel();

  if (selection == 0) return;

  // Get all selected rows
  QModelIndexList indexList = selection->selectedRows();

  for ( int i = 0 ; i < indexList.size() ; ++i) {

    BaseObject* copyItem = model_->getItem( indexList[i] );

    // remove the whole subtree below this item
    if ( PluginFunctions::copyObject(copyItem->id()) == -1 ) {
      emit log(LOGERR, "Unable to copy object" );
      continue;
    }

Jan Möbius's avatar
 
Jan Möbius committed
135
    emit updatedObject(copyItem->id());
136 137
  }

Jan Möbius's avatar
 
Jan Möbius committed
138
  emit updateView();
139 140
}

Dirk Wilden's avatar
Dirk Wilden committed
141
/// Slot for Group action in ContextMenu
Jan Möbius's avatar
 
Jan Möbius committed
142 143
void DataControlPlugin::slotGroup (  ) {
  QItemSelectionModel* selection = view_->selectionModel();
144

Jan Möbius's avatar
 
Jan Möbius committed
145
  // Get all selected rows
146
  QModelIndexList indexList = selection->selectedRows ( 0 );
Jan Möbius's avatar
 
Jan Möbius committed
147

148
  //check if all objects have the same parent
Jan Möbius's avatar
 
Jan Möbius committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  //abort if the parents differ
  BaseObject* parent = (model_->getItem( indexList[0]))->parent();
  for ( int i = 1 ; i < indexList.size() ; ++i) {
    BaseObject* item = model_->getItem( indexList[i] );
    if (parent != item->parent()){
      emit log("Cannot group Objects with different parents");
      return;
    }
  }

  //create new group
  if (parent == 0)
    parent = PluginFunctions::objectRoot();
  GroupObject* groupItem = new GroupObject( "newGroup", dynamic_cast< GroupObject* >(parent));
  groupItem->setName("newGroup " + QString::number(groupItem->id()));
  parent->appendChild( dynamic_cast< BaseObject* >( groupItem ) );
  groupItem->setParent( parent );

  //append new children to group
  for ( int i = 0 ; i < indexList.size() ; ++i) {
    BaseObject* item = model_->getItem( indexList[i] );
    item->parent()->removeChild(item);
    item->setParent( dynamic_cast< BaseObject* >( groupItem )  );
    groupItem->appendChild(item);
  }
174

Jan Möbius's avatar
 
Jan Möbius committed
175
  emit updatedObject(-1);
Jan Möbius's avatar
 
Jan Möbius committed
176 177
}

Dirk Wilden's avatar
Dirk Wilden committed
178
/// ContextMenu requested - creates the contextMenu
Jan Möbius's avatar
 
Jan Möbius committed
179 180
void DataControlPlugin::slotCustomContextMenuRequested ( const QPoint & _pos ) {
  popupIndex_ = view_->indexAt(_pos);
181

182 183 184
  if (!popupIndex_.isValid())
    return;

Jan Möbius's avatar
 
Jan Möbius committed
185
  BaseObject* item = model_->getItem(popupIndex_);
186

187

Jan Möbius's avatar
 
Jan Möbius committed
188
  QItemSelectionModel* selection = view_->selectionModel();
189

Jan Möbius's avatar
 
Jan Möbius committed
190
  // Get all selected rows
191
  QModelIndexList indexList = selection->selectedRows ( 0 );
Jan Möbius's avatar
 
Jan Möbius committed
192
  int selectedRows = indexList.size();
193

194
  Menu    menu(0);
Jan Möbius's avatar
 
Jan Möbius committed
195 196 197
  QAction* action;
  QIcon icon;
  if ( selectedRows > 1 ) {
198 199 200 201
    action = menu.addAction("Copy",this,SLOT ( slotCopy() ));
    icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-copy.png");
    action->setIcon(icon);
    menu.addAction("Group",this,SLOT ( slotGroup() ));
Jan Möbius's avatar
 
Jan Möbius committed
202
    menu.addSeparator();
203
    menu.addAction("Remove",this,SLOT ( slotPopupRemove() ));
Jan Möbius's avatar
 
Jan Möbius committed
204 205 206
   }else
    // check if the item is a group item
    if ( item->isGroup() ) {
207
      action = menu.addAction("Zoom to objects",this,SLOT ( slotZoomTo() ));
Dirk Wilden's avatar
Dirk Wilden committed
208 209
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"zoom-in.png");
      action->setIcon(icon);
210
      menu.addAction("Ungroup",this,SLOT ( slotUngroup() ));
Jan Möbius's avatar
 
Jan Möbius committed
211
      menu.addSeparator();
212
      action = menu.addAction("Rename",this,SLOT ( slotRename() ));
Jan Möbius's avatar
 
Jan Möbius committed
213 214 215
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-rename.png");
      action->setIcon(icon);
      menu.addSeparator();
216
      action = menu.addAction("Remove",this,SLOT ( slotPopupRemove() ));
Jan Möbius's avatar
 
Jan Möbius committed
217
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-delete-item.png");
Jan Möbius's avatar
 
Jan Möbius committed
218 219
      action->setIcon(icon);
    } else {
220
      action = menu.addAction("Zoom to object",this,SLOT ( slotZoomTo() ));
Dirk Wilden's avatar
Dirk Wilden committed
221 222
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"zoom-in.png");
      action->setIcon(icon);
223 224 225 226
      action = menu.addAction("Copy",this,SLOT ( slotCopy() ));
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-copy.png");
      action->setIcon(icon);
      action = menu.addAction("Rename",this,SLOT ( slotRename() ));
Jan Möbius's avatar
 
Jan Möbius committed
227 228
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-rename.png");
      action->setIcon(icon);
Dirk Wilden's avatar
Dirk Wilden committed
229 230 231
      action = menu.addAction("Material Properties",this,SLOT ( slotMaterialProperties() ));
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png");
      action->setIcon(icon);
Dirk Wilden's avatar
Dirk Wilden committed
232
      menu.addAction("Group",this,SLOT ( slotGroup() ));
Jan Möbius's avatar
 
Jan Möbius committed
233
      menu.addSeparator();
234
      action = menu.addAction("Remove",this,SLOT ( slotPopupRemove() ));
Jan Möbius's avatar
 
Jan Möbius committed
235
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-delete-item.png");
Jan Möbius's avatar
 
Jan Möbius committed
236 237
      action->setIcon(icon);
    }
238 239 240



Jan Möbius's avatar
 
Jan Möbius committed
241
  menu.exec(view_->mapToGlobal( _pos) );
242

Jan Möbius's avatar
 
Jan Möbius committed
243 244 245
}

void DataControlPlugin::slotHeaderCustomContextMenuRequested ( const QPoint & _pos ) {
246

Jan Möbius's avatar
 
Jan Möbius committed
247
  headerPopupType_ = viewHeader_->logicalIndexAt( _pos );
248

Jan Möbius's avatar
 
Jan Möbius committed
249
  QMenu menu(0);
250

Jan Möbius's avatar
 
Jan Möbius committed
251
  QIcon icon;
252 253 254



Jan Möbius's avatar
 
Jan Möbius committed
255 256 257
  switch (headerPopupType_) {
//     case 0 :
//       std::cerr << "0";
258
//       break;
Jan Möbius's avatar
 
Jan Möbius committed
259 260 261
    //Show / Hide
    case 1 :
      icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"drawModes.png");
262 263
      menu.addAction(icon,"Show all",this,SLOT ( showAll() ));
      menu.addAction("Hide all",this,SLOT ( hideAll() ));
Jan Möbius's avatar
 
Jan Möbius committed
264 265 266
      break;
    // Source
    case 2 :
267 268 269 270
      menu.addAction("Select all",this,SLOT ( setAllSource() ));
      menu.addAction("Deselect all",this,SLOT ( clearAllSource() ));
      break;
    // Target
Jan Möbius's avatar
 
Jan Möbius committed
271
    case 3 :
272 273
      menu.addAction("Select all",this,SLOT ( setAllTarget() ));
      menu.addAction("Deselect all",this,SLOT ( clearAllTarget() ));
Jan Möbius's avatar
 
Jan Möbius committed
274 275 276 277 278
      break;
    default :
//       std::cerr << "def";
      break;
  }
279

Jan Möbius's avatar
 
Jan Möbius committed
280 281 282 283 284
  menu.exec(viewHeader_->mapToGlobal( _pos ) );
}

void DataControlPlugin::slotRename(){
  QItemSelectionModel* selection = view_->selectionModel();
285

Jan Möbius's avatar
 
Jan Möbius committed
286
  // Get all selected rows
287
  QModelIndexList indexList = selection->selectedRows ( 0 );
Jan Möbius's avatar
 
Jan Möbius committed
288 289 290 291 292 293 294 295 296 297 298
  int selectedRows = indexList.size();
  if (selectedRows == 1){
    BaseObject* item = model_->getItem( indexList[0]);
    bool ok;
    QString newName = QInputDialog::getText(0, tr("Rename"),
                                            tr("Enter a new name:"), QLineEdit::Normal,
                                            item->name(), &ok);
    if (ok && !newName.isEmpty())
      item->setName(newName);
  }
}
Dirk Wilden's avatar
Dirk Wilden committed
299

Dirk Wilden's avatar
Dirk Wilden committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
void DataControlPlugin::slotMaterialProperties(){
  QItemSelectionModel* selection = view_->selectionModel();

  // Get all selected rows
  QModelIndexList indexList = selection->selectedRows ( 0 );
  int selectedRows = indexList.size();
  if (selectedRows == 1){
    BaseObject* item = model_->getItem( indexList[0]);

    BaseObjectData* itemData = dynamic_cast< BaseObjectData* > (item);

    ACG::QtWidgets::QtMaterialDialog* dialog = new ACG::QtWidgets::QtMaterialDialog( 0, itemData->materialNode() );

    dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);

    connect(dialog, SIGNAL(signalNodeChanged(ACG::SceneGraph::BaseNode*)),
            this,   SLOT(slotNodeChanged(ACG::SceneGraph::BaseNode*)) );

    dialog->setWindowIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png"));

    dialog->show();

  }
}

///Called when the material properties were changed inside the material dialog
void DataControlPlugin::slotNodeChanged( ACG::SceneGraph::BaseNode* /*_node*/ ){
Jan Möbius's avatar
 
Jan Möbius committed
327
  emit updateView();
Dirk Wilden's avatar
Dirk Wilden committed
328 329
}

Dirk Wilden's avatar
Dirk Wilden committed
330 331
void DataControlPlugin::slotZoomTo(){
  QItemSelectionModel* selection = view_->selectionModel();
332

Dirk Wilden's avatar
Dirk Wilden committed
333
  // Get all selected rows
334
  QModelIndexList indexList = selection->selectedRows ( 0 );
Dirk Wilden's avatar
Dirk Wilden committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
  int selectedRows = indexList.size();
  if (selectedRows == 1){
    BaseObject* item = model_->getItem( indexList[0]);

    if ( item->isGroup() ) {
      //zoom to all objects in this group
      QList< BaseObject* > children = item->getLeafs();

      //compute boundingBox
      bool firstRound = true;
      ACG::Vec3d bbmin;
      ACG::Vec3d bbmax;

      for (int i=0; i < children.size(); i++){
        BaseObjectData* child = dynamic_cast< BaseObjectData* > (children[i]);
        if (child){
          ACG::Vec3d cur_min;
          ACG::Vec3d cur_max;
353

Dirk Wilden's avatar
Dirk Wilden committed
354
          child->getBoundingBox(cur_min, cur_max);
355

Dirk Wilden's avatar
Dirk Wilden committed
356 357 358 359 360 361 362 363 364 365 366 367
          if (firstRound){
            bbmin = cur_min;
            bbmax = cur_max;
            firstRound = false;
          }else{
            bbmin[0] = std::min( bbmin[0], cur_min[0]);
            bbmin[1] = std::min( bbmin[1], cur_min[1]);
            bbmin[2] = std::min( bbmin[2], cur_min[2]);
            bbmax[0] = std::max( bbmax[0], cur_max[0]);
            bbmax[1] = std::max( bbmax[0], cur_max[1]);
            bbmax[2] = std::max( bbmax[0], cur_max[2]);
          }
368

Dirk Wilden's avatar
Dirk Wilden committed
369 370 371
        }
      }
      //zoom to objects
Dirk Wilden's avatar
Dirk Wilden committed
372
      ACG::Vec3d bbcenter = (bbmax + bbmin) * 0.5;
373

Dirk Wilden's avatar
Dirk Wilden committed
374
      double bbradius = (bbmax - bbmin).norm();
375

Dirk Wilden's avatar
Dirk Wilden committed
376
      ACG::Vec3d eye = bbcenter + (PluginFunctions::eyePos() - bbcenter).normalize() * bbradius ;
377

Dirk Wilden's avatar
Dirk Wilden committed
378
      PluginFunctions::flyTo(eye, bbcenter );
379

Dirk Wilden's avatar
Dirk Wilden committed
380 381 382
    }else{
      //zoom to object
      BaseObjectData* obj = dynamic_cast< BaseObjectData* >(item);
383

Dirk Wilden's avatar
Dirk Wilden committed
384
      if (obj){
385

Dirk Wilden's avatar
Dirk Wilden committed
386 387
        ACG::Vec3d bbmin;
        ACG::Vec3d bbmax;
388

Dirk Wilden's avatar
Dirk Wilden committed
389
        obj->getBoundingBox(bbmin, bbmax);
390

Dirk Wilden's avatar
Dirk Wilden committed
391 392
        if ((bbmin[0] > bbmax[0]) || (bbmin[1] > bbmax[1]) || (bbmin[2] > bbmax[2]))
          std::cerr << "Error while computing bounding box!";
393

Dirk Wilden's avatar
Dirk Wilden committed
394
        ACG::Vec3d bbcenter = (bbmax + bbmin) * 0.5;
395

Dirk Wilden's avatar
Dirk Wilden committed
396
        double bbradius = (bbmax - bbmin).norm();
397

Dirk Wilden's avatar
Dirk Wilden committed
398
        ACG::Vec3d eye = bbcenter + (PluginFunctions::eyePos() - bbcenter).normalize() * bbradius ;
399

Dirk Wilden's avatar
Dirk Wilden committed
400 401 402 403 404
        PluginFunctions::flyTo(eye, bbcenter );
      }
    }
  }
}