Преглед изворни кода

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 година
родитељ
комит
ebaddbb865

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

@@ -33,19 +33,22 @@
 int ctkColorDialogTest2(int argc, char * 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" )
     {
-    // 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()));
-    // quit the application
     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();
 }

+ 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" )
     {
-    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()));
 
   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(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()));
 
   return app.exec();

+ 54 - 6
Libs/Widgets/ctkPathLineEdit.cpp

@@ -52,6 +52,11 @@ public:
   QString               Label;              //!< used in file dialogs
   QStringList           NameFilters;        //!< Regular expression (in wildcard mode) used to help the user to complete the line
   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
 
@@ -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()
 {
   Q_D(ctkPathLineEdit);
@@ -190,18 +217,33 @@ void ctkPathLineEdit::browse()
     {
     if ( d->Filters & QDir::Writable) // load or save
       {
-      path = QFileDialog::getSaveFileName(this,
+      path = QFileDialog::getSaveFileName(
+	this,
         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
       {
       path = QFileDialog::getOpenFileName(
         this,
         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
@@ -209,7 +251,13 @@ void ctkPathLineEdit::browse()
     path = QFileDialog::getExistingDirectory(
       this,
       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())
     {

+ 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 ( Filters filters READ filters WRITE setFilters)
   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:
   enum Filter { Dirs        = 0x001,
                 Files       = 0x002,
@@ -90,6 +100,21 @@ public:
   };
   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
   */
   ctkPathLineEdit(QWidget *parent = 0);
@@ -116,6 +141,16 @@ public:
   void setFilters(const Filters& filters);
   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.
    *  If there is no extension yet, set it
   */
@@ -160,5 +195,8 @@ private:
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPathLineEdit::Filters)
+#ifndef USE_QFILEDIALOG_OPTIONS
+Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPathLineEdit::Options);
+#endif
 
 #endif // __ctkPathLineEdit_h