Ver código fonte

Don't use native dialogs in tests, they won't quit

Because native dialogs don't use Qt event loops, qtimer to quit the app
don't work.
We need to enforce the dialogs are using Qt custom dialogs instead of
native OS dialogs.
Add ctkPathLineEdit::Options property to control options on the dialogs
used in ctkPathLineEdit::browse(). It's identical to ctkDirectoryButton
Julien Finet 14 anos atrás
pai
commit
ebaddbb865

+ 8 - 5
Libs/Widgets/Testing/Cpp/ctkColorDialogTest2.cpp

@@ -33,19 +33,22 @@
 int ctkColorDialogTest2(int argc, char * argv [] )
 int ctkColorDialogTest2(int argc, char * argv [] )
 {
 {
   QApplication app(argc, argv);
   QApplication app(argc, argv);
+  app.setQuitOnLastWindowClosed(true);
 
 
-  ctkColorPickerButton* extraPanel = new ctkColorPickerButton;
-  ctkColorDialog::addDefaultTab(extraPanel, "Extra", SIGNAL(colorChanged(QColor)));
+  ctkColorPickerButton extraPanel;
+  ctkColorDialog::addDefaultTab(&extraPanel, "Extra", SIGNAL(colorChanged(QColor)));
 
 
   if (argc < 2 || QString(argv[1]) != "-I" )
   if (argc < 2 || QString(argv[1]) != "-I" )
     {
     {
-    // quit for the first event loop of the opened dialog
+    // quit the opened dialog, which doesn't quit the application
+    // as app.exec() is not executed yet
     QTimer::singleShot(200, &app, SLOT(quit()));
     QTimer::singleShot(200, &app, SLOT(quit()));
-    // quit the application
     QTimer::singleShot(300, &app, SLOT(quit()));
     QTimer::singleShot(300, &app, SLOT(quit()));
     }
     }
 
 
-  QColor color = ctkColorDialog::getColor(Qt::black,0 , "", 0);
+  // The opened dialog blocks QTimers which prevents the test
+  // from being quit.
+  QColor color = ctkColorDialog::getColor(Qt::black,0 , "", QColorDialog::DontUseNativeDialog);
   
   
   return app.exec();
   return app.exec();
 }
 }

+ 5 - 2
Libs/Widgets/Testing/Cpp/ctkDirectoryButtonTest1.cpp

@@ -120,11 +120,14 @@ int ctkDirectoryButtonTest1(int argc, char * argv [] )
 
 
   if (argc < 2 || QString(argv[1]) != "-I" )
   if (argc < 2 || QString(argv[1]) != "-I" )
     {
     {
-    QTimer::singleShot(200, &app, SLOT(quit()));
+    QTimer::singleShot(400, &app, SLOT(quit()));
     }
     }
 
 
+  // If Qt uses the default native dialog, a nested event loop won't
+  // be created and app.quit() will have no effect (as it solely quits
+  // event loops).
+  button.setOptions(button.options() | ctkDirectoryButton::DontUseNativeDialog);
   QTimer::singleShot(100, &button, SLOT(browse()));
   QTimer::singleShot(100, &button, SLOT(browse()));
 
 
   return app.exec();
   return app.exec();
 }
 }
-

+ 2 - 0
Libs/Widgets/Testing/Cpp/ctkPathLineEditTest1.cpp

@@ -103,6 +103,8 @@ int ctkPathLineEditTest1(int argc, char * argv [] )
 
 
   QTimer::singleShot(100, &button, SLOT(retrieveHistory()));
   QTimer::singleShot(100, &button, SLOT(retrieveHistory()));
   QTimer::singleShot(115, &button2, SLOT(addCurrentPathToHistory()));
   QTimer::singleShot(115, &button2, SLOT(addCurrentPathToHistory()));
+  // The open dialog blocks QTimers (to quit the app).
+  button3.setOptions(button3.options() | ctkPathLineEdit::DontUseNativeDialog);
   QTimer::singleShot(120, &button3, SLOT(browse()));
   QTimer::singleShot(120, &button3, SLOT(browse()));
 
 
   return app.exec();
   return app.exec();

+ 54 - 6
Libs/Widgets/ctkPathLineEdit.cpp

@@ -52,6 +52,11 @@ public:
   QString               Label;              //!< used in file dialogs
   QString               Label;              //!< used in file dialogs
   QStringList           NameFilters;        //!< Regular expression (in wildcard mode) used to help the user to complete the line
   QStringList           NameFilters;        //!< Regular expression (in wildcard mode) used to help the user to complete the line
   QDir::Filters         Filters;            //!< Type of path (file, dir...)
   QDir::Filters         Filters;            //!< Type of path (file, dir...)
+#ifdef USE_QFILEDIALOG_OPTIONS
+  QFileDialog::Options DialogOptions;
+#else
+  ctkPathLineEdit::Options DialogOptions;
+#endif
 
 
   bool                  HasValidInput;      //!< boolean that stores the old state of valid input
   bool                  HasValidInput;      //!< boolean that stores the old state of valid input
 
 
@@ -182,6 +187,28 @@ ctkPathLineEdit::Filters ctkPathLineEdit::filters()const
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
+#ifdef USE_QFILEDIALOG_OPTIONS
+void ctkPathLineEdit::setOptions(const QFileDialog::Options& dialogOptions)
+#else
+void ctkPathLineEdit::setOptions(const Options& dialogOptions)
+#endif
+{
+  Q_D(ctkPathLineEdit);
+  d->DialogOptions = dialogOptions;
+}
+
+//-----------------------------------------------------------------------------
+#ifdef USE_QFILEDIALOG_OPTIONS
+const QFileDialog::Options& ctkPathLineEdit::options()const
+#else
+const ctkPathLineEdit::Options& ctkPathLineEdit::options()const
+#endif
+{
+  Q_D(const ctkPathLineEdit);
+  return d->DialogOptions;
+}
+
+//-----------------------------------------------------------------------------
 void ctkPathLineEdit::browse()
 void ctkPathLineEdit::browse()
 {
 {
   Q_D(ctkPathLineEdit);
   Q_D(ctkPathLineEdit);
@@ -190,18 +217,33 @@ void ctkPathLineEdit::browse()
     {
     {
     if ( d->Filters & QDir::Writable) // load or save
     if ( d->Filters & QDir::Writable) // load or save
       {
       {
-      path = QFileDialog::getSaveFileName(this,
+      path = QFileDialog::getSaveFileName(
+	this,
         tr("Select a file to save "),
         tr("Select a file to save "),
-        this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory : this->currentPath(),
-                                          d->NameFilters.join(";;"));
+        this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory :
+	                                this->currentPath(),
+	d->NameFilters.join(";;"),
+	0,
+#ifdef USE_QFILEDIALOG_OPTIONS
+      d->DialogOptions);
+#else
+      QFlags<QFileDialog::Option>(int(d->DialogOptions)));
+#endif
       }
       }
     else
     else
       {
       {
       path = QFileDialog::getOpenFileName(
       path = QFileDialog::getOpenFileName(
         this,
         this,
         QString("Open a file"),
         QString("Open a file"),
-        this->currentPath().isEmpty()? ctkPathLineEditPrivate::sCurrentDirectory : this->currentPath(),
-        d->NameFilters.join(";;"));
+        this->currentPath().isEmpty()? ctkPathLineEditPrivate::sCurrentDirectory :
+	                               this->currentPath(),
+        d->NameFilters.join(";;"),
+	0,
+#ifdef USE_QFILEDIALOG_OPTIONS
+      d->DialogOptions);
+#else
+      QFlags<QFileDialog::Option>(int(d->DialogOptions)));
+#endif
       }
       }
     }
     }
   else //directory
   else //directory
@@ -209,7 +251,13 @@ void ctkPathLineEdit::browse()
     path = QFileDialog::getExistingDirectory(
     path = QFileDialog::getExistingDirectory(
       this,
       this,
       QString("Select a directory..."),
       QString("Select a directory..."),
-      this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory : this->currentPath());
+      this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory :
+                                      this->currentPath(),
+#ifdef USE_QFILEDIALOG_OPTIONS
+      d->DialogOptions);
+#else
+      QFlags<QFileDialog::Option>(int(d->DialogOptions)));
+#endif
     }
     }
   if (path.isEmpty())
   if (path.isEmpty())
     {
     {

+ 38 - 0
Libs/Widgets/ctkPathLineEdit.h

@@ -66,6 +66,16 @@ class CTK_WIDGETS_EXPORT ctkPathLineEdit: public QWidget
   Q_PROPERTY ( QStringList nameFilters READ nameFilters WRITE setNameFilters)
   Q_PROPERTY ( QStringList nameFilters READ nameFilters WRITE setNameFilters)
   Q_PROPERTY ( Filters filters READ filters WRITE setFilters)
   Q_PROPERTY ( Filters filters READ filters WRITE setFilters)
   Q_PROPERTY ( QString currentPath READ currentPath WRITE setCurrentPath USER true )
   Q_PROPERTY ( QString currentPath READ currentPath WRITE setCurrentPath USER true )
+  /// Qt versions prior to 4.7.0 didn't expose QFileDialog::Options in the
+  /// public API. We need to create a custom property that will be used when
+  /// instanciating a QFileDialog in ctkPathLineEdit::browse()
+#ifdef USE_QFILEDIALOG_OPTIONS
+  Q_PROPERTY(QFileDialog::Options options READ options WRITE setOptions)
+#else
+  Q_PROPERTY(Options options READ options WRITE setOptions)
+  Q_FLAGS(Option Options);
+#endif
+
 public:
 public:
   enum Filter { Dirs        = 0x001,
   enum Filter { Dirs        = 0x001,
                 Files       = 0x002,
                 Files       = 0x002,
@@ -90,6 +100,21 @@ public:
   };
   };
   Q_DECLARE_FLAGS(Filters, Filter)
   Q_DECLARE_FLAGS(Filters, Filter)
 
 
+#ifndef USE_QFILEDIALOG_OPTIONS
+  // Same options than QFileDialog::Options
+  enum Option
+  {
+    ShowDirsOnly          = 0x00000001,
+    DontResolveSymlinks   = 0x00000002,
+    DontConfirmOverwrite  = 0x00000004,
+    DontUseSheet          = 0x00000008,
+    DontUseNativeDialog   = 0x00000010,
+    ReadOnly              = 0x00000020,
+    HideNameFilterDetails = 0x00000040
+  };
+  Q_DECLARE_FLAGS(Options, Option)
+#endif
+
   /** Default constructor
   /** Default constructor
   */
   */
   ctkPathLineEdit(QWidget *parent = 0);
   ctkPathLineEdit(QWidget *parent = 0);
@@ -116,6 +141,16 @@ public:
   void setFilters(const Filters& filters);
   void setFilters(const Filters& filters);
   Filters filters()const;
   Filters filters()const;
 
 
+  /// Options of the file dialog pop up.
+  /// \sa QFileDialog::getExistingDirectory
+#ifdef USE_QFILEDIALOG_OPTIONS
+  void setOptions(const QFileDialog::Options& options);
+  const QFileDialog::Options& options()const;
+#else
+  void setOptions(const Options& options);
+  const Options& options()const;
+#endif
+
   /** Change the current extension of the edit line.
   /** Change the current extension of the edit line.
    *  If there is no extension yet, set it
    *  If there is no extension yet, set it
   */
   */
@@ -160,5 +195,8 @@ private:
 };
 };
 
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPathLineEdit::Filters)
 Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPathLineEdit::Filters)
+#ifndef USE_QFILEDIALOG_OPTIONS
+Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPathLineEdit::Options);
+#endif
 
 
 #endif // __ctkPathLineEdit_h
 #endif // __ctkPathLineEdit_h