From b7e49eee71b83fdde33b6c0910a023ba68e2e7c2 Mon Sep 17 00:00:00 2001
From: Marco Biasini <marco.biasini@unibas.ch>
Date: Mon, 20 Dec 2010 10:41:07 +0100
Subject: [PATCH] file type dialog: double click on file type triggers loading

this seemingly simple change required a rather gross hack to avoid a crash when
the file type dialog is destroyed. Currently the FileTypeDialog is allocated on
the heap an leaks. This is not nice, but since the file type dialog is very
rarely used, this seems to be something we can live with for the moment. I've
opened ticket BZDNG-192 to track the issue.
---
 modules/gui/src/file_loader.cc      |  26 +++---
 modules/gui/src/file_type_dialog.cc | 129 ++++++++++++++++------------
 modules/gui/src/file_type_dialog.hh |   9 +-
 3 files changed, 92 insertions(+), 72 deletions(-)

diff --git a/modules/gui/src/file_loader.cc b/modules/gui/src/file_loader.cc
index ac35f1a6a..b013bdfdf 100644
--- a/modules/gui/src/file_loader.cc
+++ b/modules/gui/src/file_loader.cc
@@ -132,21 +132,24 @@ void FileLoader::AddToScene(const QString& filename, gfx::GfxObjP obj)
 
 gfx::GfxObjP FileLoader::NoHandlerFound(const QString& filename)
 {
-  FileTypeDialog dialog(filename);
+  /// FIXME: This currently leaks! I haven't found a way to allocate the dialog 
+  /// on the stack without crashing the program.
+  /// This is BZDNG-192
+  FileTypeDialog* dialog=new FileTypeDialog(filename);
   try{
-    if(dialog.exec()){
-      if(dialog.GetEntityHandler()){
-        return TryLoadEntity(filename, dialog.GetEntityHandler());
+    if(dialog->exec()){
+      if(dialog->GetEntityHandler()){
+        return TryLoadEntity(filename, dialog->GetEntityHandler());
       }
-      if(dialog.GetSequenceHandler()){
-        return TryLoadAlignment(filename, dialog.GetSequenceHandler());
+      if(dialog->GetSequenceHandler()){
+        return TryLoadAlignment(filename, dialog->GetSequenceHandler());
       }
-      if(dialog.GetSurfaceHandler()){
-        return TryLoadSurface(filename,dialog.GetSurfaceHandler());
+      if(dialog->GetSurfaceHandler()){
+        return TryLoadSurface(filename,dialog->GetSurfaceHandler());
       }
   #if OST_IMG_ENABLED
-      if(dialog.GetMapHandler()){
-        return TryLoadMap(filename,dialog.GetMapHandler());
+      if(dialog->GetMapHandler()){
+        return TryLoadMap(filename,dialog->GetMapHandler());
       }
   #endif
     }
@@ -251,7 +254,8 @@ gfx::GfxObjP FileLoader::TryLoadEntity(const QString& filename, io::EntityIOHand
           conop::BuilderP builder = conop::Conopology::Instance().GetBuilder();
           conop::Conopology::Instance().ConnectAll(builder,eh,0);
       }
-      gfx::GfxObjP obj(new gfx::Entity(file_info.baseName().toStdString(),eh,mol::Query(selection.toStdString())));
+      gfx::GfxObjP obj(new gfx::Entity(file_info.baseName().toStdString(),
+                       eh, mol::Query(selection.toStdString())));
       return obj;
     }
   }
diff --git a/modules/gui/src/file_type_dialog.cc b/modules/gui/src/file_type_dialog.cc
index caf11bc83..d0a45602e 100644
--- a/modules/gui/src/file_type_dialog.cc
+++ b/modules/gui/src/file_type_dialog.cc
@@ -29,6 +29,75 @@
 #include <QHeaderView>
 namespace ost { namespace gui {
 
+
+namespace {
+
+class FileTypeList : public QTableWidget {
+public:
+  FileTypeList(QWidget* parent=NULL): QTableWidget(parent)
+  {
+    this->setShowGrid(false);
+    this->horizontalHeader()->setStretchLastSection(true);
+    this->setColumnCount(2);
+    this->setAttribute(Qt::WA_MacSmallSize);
+    this->verticalHeader()->setVisible(false);
+    this->horizontalHeader()->setVisible(false);
+    this->setSelectionBehavior(QAbstractItemView::SelectRows);
+    this->setSelectionMode(QAbstractItemView::SingleSelection); 
+    io::EntityIOHFList entity_handler = io::IOManager::Instance().GetAvailableEntityHandler();
+    for(unsigned int i = 0 ; i < entity_handler.size() ; i++){
+      QVariant handler = QVariant();
+      handler.setValue(entity_handler[i]);
+      this->AddRow(this->rowCount(),entity_handler[i]->GetFormatName().c_str(),entity_handler[i]->GetFormatDescription().c_str(),handler);
+    }
+
+    io::AlignmentIOFList alignment_handler = io::IOManager::Instance().GetAvailableAlignmentHandler();
+    for(unsigned int i = 0 ; i < alignment_handler.size() ; i++){
+      QVariant handler = QVariant();
+      handler.setValue(alignment_handler[i]);
+      this->AddRow(this->rowCount(),alignment_handler[i]->GetFormatName().c_str(),alignment_handler[i]->GetFormatDescription().c_str(),handler);
+    }
+
+#if OST_IMG_ENABLED
+    io::MapIOFList map_handler = io::IOManager::Instance().GetAvailableMapHandler();
+    for(unsigned int i = 0 ; i < map_handler.size() ; i++){
+      QVariant handler = QVariant();
+      handler.setValue(map_handler[i]);
+      this->AddRow(this->rowCount(),map_handler[i]->GetFormatName().c_str(),map_handler[i]->GetFormatDescription().c_str(),handler);
+    }
+#endif
+
+    io::SurfaceIOFList surf_handler = io::IOManager::Instance().GetAvailableSurfaceHandler();
+    for(unsigned int i = 0 ; i < surf_handler.size() ; i++){
+      QVariant handler = QVariant();
+      handler.setValue(surf_handler[i]);
+      this->AddRow(this->rowCount(),surf_handler[i]->GetFormatName().c_str(),surf_handler[i]->GetFormatDescription().c_str(),handler);
+    }
+  }
+  
+  virtual void mouseDoubleClickEvent(QMouseEvent* event)
+  {
+    QTableWidget::mouseDoubleClickEvent(event);
+    dynamic_cast<QDialog*>(parent())->accept();
+  }
+  
+  void AddRow(int row, const QString& format_name, const QString& format_descr, 
+              QVariant& variant)
+  {
+    this->insertRow(row);
+    QTableWidgetItem* new_item = new QTableWidgetItem(format_name);
+    new_item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+    new_item->setData(Qt::UserRole,variant);
+    this->setItem(row, 0, new_item);
+    new_item = new QTableWidgetItem(format_descr);
+    new_item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+    this->setItem(row, 1, new_item);
+  }
+};
+
+}
+
+
 FileTypeDialog::FileTypeDialog(const QString& file_name, QWidget* parent):
   QDialog(parent),entity_handler_(),seq_handler_(), surf_handler_()
 #if OST_IMG_ENABLED
@@ -41,16 +110,9 @@ FileTypeDialog::FileTypeDialog(const QString& file_name, QWidget* parent):
   label_ = new QLabel("The file format could not be recognized, "
                       "please select the type of the file from the list:");
   label_->setWordWrap(true);
-  list_ = new QTableWidget(this);
-  list_->setShowGrid(false);
-  list_->horizontalHeader()->setStretchLastSection(true);
-  list_->setColumnCount(2);
-  list_->setAttribute(Qt::WA_MacSmallSize);
-  list_->verticalHeader()->setVisible(false);
-  list_->horizontalHeader()->setVisible(false);
-  list_->setSelectionBehavior(QAbstractItemView::SelectRows);
-  list_->setSelectionMode(QAbstractItemView::SingleSelection);
-  QHBoxLayout* hb=new QHBoxLayout();  
+  list_ = new FileTypeList(this);
+
+  QHBoxLayout* hb=new QHBoxLayout;  
   vb->addWidget(label_);
   vb->addWidget(list_);
   hb->setDirection(QBoxLayout::LeftToRight);
@@ -63,52 +125,11 @@ FileTypeDialog::FileTypeDialog(const QString& file_name, QWidget* parent):
   load_btn->setDefault(true);
   connect(load_btn, SIGNAL(clicked()), this, SLOT(accept()));
   connect(cancel_btn, SIGNAL(clicked()), this, SLOT(reject()));
-
-  io::EntityIOHFList entity_handler = io::IOManager::Instance().GetAvailableEntityHandler();
-  for(unsigned int i = 0 ; i < entity_handler.size() ; i++){
-    QVariant handler = QVariant();
-    handler.setValue(entity_handler[i]);
-    this->AddRow(list_->rowCount(),entity_handler[i]->GetFormatName().c_str(),entity_handler[i]->GetFormatDescription().c_str(),handler);
-  }
-
-  io::AlignmentIOFList alignment_handler = io::IOManager::Instance().GetAvailableAlignmentHandler();
-  for(unsigned int i = 0 ; i < alignment_handler.size() ; i++){
-    QVariant handler = QVariant();
-    handler.setValue(alignment_handler[i]);
-    this->AddRow(list_->rowCount(),alignment_handler[i]->GetFormatName().c_str(),alignment_handler[i]->GetFormatDescription().c_str(),handler);
-  }
-
-#if OST_IMG_ENABLED
-  io::MapIOFList map_handler = io::IOManager::Instance().GetAvailableMapHandler();
-  for(unsigned int i = 0 ; i < map_handler.size() ; i++){
-    QVariant handler = QVariant();
-    handler.setValue(map_handler[i]);
-    this->AddRow(list_->rowCount(),map_handler[i]->GetFormatName().c_str(),map_handler[i]->GetFormatDescription().c_str(),handler);
-  }
-#endif
-
-  io::SurfaceIOFList surf_handler = io::IOManager::Instance().GetAvailableSurfaceHandler();
-  for(unsigned int i = 0 ; i < surf_handler.size() ; i++){
-    QVariant handler = QVariant();
-    handler.setValue(surf_handler[i]);
-    this->AddRow(list_->rowCount(),surf_handler[i]->GetFormatName().c_str(),surf_handler[i]->GetFormatDescription().c_str(),handler);
-  }
-
   list_->resizeColumnsToContents();
 }
 
-void FileTypeDialog::AddRow(int row, const QString& format_name, const QString& format_descr, QVariant& variant){
-  list_->insertRow(row);
-  QTableWidgetItem* new_item = new QTableWidgetItem(format_name);
-  new_item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
-  new_item->setData(Qt::UserRole,variant);
-  list_->setItem(row, 0, new_item);
-  new_item = new QTableWidgetItem(format_descr);
-  new_item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
-  list_->setItem(row, 1, new_item);
-}
-
-void FileTypeDialog::accept(){
+void FileTypeDialog::accept()
+{
   QList<QTableWidgetItem*> items = list_->selectedItems();
   for(int i=0; i<items.size();i++){
     if(items[i]->column()==0){
@@ -137,7 +158,7 @@ void FileTypeDialog::accept(){
 #endif
     }
   }
-  this->QDialog::accept();
+  QDialog::accept();
 }
 
 io::EntityIOHandlerP FileTypeDialog::GetEntityHandler(){
diff --git a/modules/gui/src/file_type_dialog.hh b/modules/gui/src/file_type_dialog.hh
index 2ce157556..b711cbe22 100644
--- a/modules/gui/src/file_type_dialog.hh
+++ b/modules/gui/src/file_type_dialog.hh
@@ -20,7 +20,7 @@
 #define OST_GUI_FILE_TYPE_DIALOG_HH
 
 /*
-  Author: Stefan Scheuber
+  Author: Stefan Scheuber, Marco Biasini
  */
 
 #include <ost/gui/module_config.hh>
@@ -51,14 +51,9 @@ public:
 #if OST_IMG_ENABLED
   io::MapIOHandlerPtr GetMapHandler();
 #endif
-
 public slots:
-  virtual void accept ();
-
+  virtual void accept();
 private:
-  void AddRow(int row, const QString& format_name, const QString& format_descr, QVariant& variant);
-
-
   QTableWidget* list_;
   QLabel* label_;
   io::EntityIOHandlerP entity_handler_;
-- 
GitLab