Sfoglia il codice sorgente

ENH: Add ctkFileDialog, a configurable QFileDialog

Extra items can be added to the file dialog.
Julien Finet 15 anni fa
parent
commit
44b88bb4aa

+ 3 - 0
Libs/Widgets/CMakeLists.txt

@@ -40,6 +40,8 @@ SET(KIT_SRCS
   ctkDoubleSlider.h
   ctkDynamicSpacer.cpp
   ctkDynamicSpacer.h
+  ctkFileDialog.cpp
+  ctkFileDialog.h
   ctkFittedTextBrowser.cpp
   ctkFittedTextBrowser.h
   ctkMatrixWidget.cpp
@@ -88,6 +90,7 @@ SET(KIT_MOC_SRCS
   ctkDoubleRangeSlider.h
   ctkDoubleSlider.h
   ctkDynamicSpacer.h
+  ctkFileDialog.h
   ctkFittedTextBrowser.h
   ctkMatrixWidget.h
   ctkMenuButton.h

+ 2 - 0
Libs/Widgets/Testing/Cpp/CMakeLists.txt

@@ -12,6 +12,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cxx
   ctkCoordinatesWidgetTest1.cpp
   ctkDoubleRangeSliderTest1.cpp
   ctkDoubleSliderTest1.cpp
+  ctkFileDialogTest1.cpp
   ctkFittedTextBrowserTest1.cpp
   ctkMatrixWidgetTest1.cpp
   ctkRangeSliderTest1.cpp
@@ -53,6 +54,7 @@ SIMPLE_TEST( ctkComboBoxTest1 )
 SIMPLE_TEST( ctkCoordinatesWidgetTest1 )
 SIMPLE_TEST( ctkDoubleRangeSliderTest1 )
 SIMPLE_TEST( ctkDoubleSliderTest1 )
+SIMPLE_TEST( ctkFileDialogTest1 )
 SIMPLE_TEST( ctkFittedTextBrowserTest1 )
 SIMPLE_TEST( ctkMatrixWidgetTest1 )
 SIMPLE_TEST( ctkRangeSliderTest1 )

+ 61 - 0
Libs/Widgets/Testing/Cpp/ctkFileDialogTest1.cpp

@@ -0,0 +1,61 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QCheckBox>
+
+// CTK includes
+#include "ctkFileDialog.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkFileDialogTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkFileDialog fileDialog;
+  fileDialog.setFileMode(QFileDialog::AnyFile);
+  fileDialog.setNameFilter("Images (*.png *.xpm *.jpg)");
+  fileDialog.setViewMode(QFileDialog::Detail);
+  QCheckBox* checkBox = new QCheckBox;
+  fileDialog.setBottomWidget(checkBox, "Foo Bar:");
+  if (checkBox != fileDialog.bottomWidget())
+    {
+    return EXIT_FAILURE;
+    }
+  // the following is only in interactive mode
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    return EXIT_SUCCESS;
+    }
+  QObject::connect(checkBox, SIGNAL(toggled(bool)),
+                   &fileDialog, SLOT(setAcceptButtonEnable(bool)));
+  fileDialog.setAcceptButtonEnable(false);
+  if (!fileDialog.exec())
+    {
+    return EXIT_FAILURE;
+    }
+  return EXIT_SUCCESS;
+
+}

+ 154 - 0
Libs/Widgets/ctkFileDialog.cpp

@@ -0,0 +1,154 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// QT includes
+#include <QDebug>
+#include <QDialogButtonBox>
+#include <QEvent>
+#include <QGridLayout>
+#include <QLabel>
+#include <QPushButton>
+
+// CTK includes
+#include "ctkFileDialog.h"
+
+//------------------------------------------------------------------------------
+class ctkFileDialogPrivate: public ctkPrivate<ctkFileDialog>
+{
+public:
+  ctkFileDialogPrivate();
+  void init();
+  QPushButton* acceptButton()const;
+  bool AcceptButtonEnable;
+  bool AcceptButtonState;
+  bool IgnoreEvent;
+};
+
+//------------------------------------------------------------------------------
+ctkFileDialogPrivate::ctkFileDialogPrivate()
+{
+  this->IgnoreEvent = false;
+  this->AcceptButtonEnable = true;
+  this->AcceptButtonState = true;
+}
+
+//------------------------------------------------------------------------------
+void ctkFileDialogPrivate::init()
+{
+  CTK_P(ctkFileDialog);
+  QPushButton* button = this->acceptButton();
+  Q_ASSERT(button);
+  this->AcceptButtonState =
+    button->isEnabledTo(qobject_cast<QWidget*>(button->parent()));
+  button->installEventFilter(p);
+}
+
+//------------------------------------------------------------------------------
+QPushButton* ctkFileDialogPrivate::acceptButton()const
+{
+  CTK_P(const ctkFileDialog);
+  QDialogButtonBox* buttonBox = p->findChild<QDialogButtonBox*>();
+  Q_ASSERT(buttonBox);
+  QDialogButtonBox::StandardButton button =
+    (p->acceptMode() == QFileDialog::AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
+  return buttonBox->button(button);
+}
+
+//------------------------------------------------------------------------------
+ctkFileDialog::ctkFileDialog(QWidget *parentWidget,
+              const QString &caption,
+              const QString &directory,
+              const QString &filter)
+  :QFileDialog(parentWidget, caption, directory, filter)
+{
+  CTK_INIT_PRIVATE(ctkFileDialog);
+  CTK_D(ctkFileDialog);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkFileDialog::~ctkFileDialog()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkFileDialog::setBottomWidget(QWidget* widget, const QString& label)
+{
+  QGridLayout* gridLayout = qobject_cast<QGridLayout*>(this->layout());
+  QWidget* oldBottomWidget = this->bottomWidget();
+  if (oldBottomWidget)
+    {
+    if (oldBottomWidget == widget)
+      {
+      return;
+      }
+    gridLayout->removeWidget(oldBottomWidget);
+    delete oldBottomWidget;
+    }
+  if (widget == 0)
+    {
+    return;
+    }
+  if (!label.isEmpty())
+    {
+    gridLayout->addWidget(new QLabel(label), 4, 0);
+    gridLayout->addWidget(widget,4, 1,1, 1);
+    }
+  else
+    {
+    gridLayout->addWidget(widget,4, 0,1, 2);
+    }
+  QDialogButtonBox* buttonBox = this->findChild<QDialogButtonBox*>();
+  Q_ASSERT(buttonBox);
+  gridLayout->removeWidget(buttonBox);
+  gridLayout->addWidget(buttonBox, 2, 2, 3, 1);
+}
+
+//------------------------------------------------------------------------------
+QWidget* ctkFileDialog::bottomWidget()const
+{
+  QGridLayout* gridLayout = qobject_cast<QGridLayout*>(this->layout());
+  QLayoutItem* item = gridLayout->itemAtPosition(4,1);
+  return item ? item->widget() : 0;
+}
+
+//------------------------------------------------------------------------------
+void ctkFileDialog::setAcceptButtonEnable(bool enable)
+{
+  CTK_D(ctkFileDialog);
+  d->AcceptButtonEnable = enable;
+  d->acceptButton()->setEnabled(d->AcceptButtonEnable && d->AcceptButtonState);
+}
+
+//------------------------------------------------------------------------------
+bool ctkFileDialog::eventFilter(QObject *obj, QEvent *event)
+{
+  CTK_D(ctkFileDialog);
+  QPushButton* button = d->acceptButton();
+  if (obj == button && event->type() == QEvent::EnabledChange &&
+      !d->IgnoreEvent)
+    {
+    d->IgnoreEvent = true;
+    d->AcceptButtonState = button->isEnabledTo(qobject_cast<QWidget*>(button->parent()));
+    button->setEnabled(d->AcceptButtonEnable && d->AcceptButtonState);
+    d->IgnoreEvent = false;
+    }
+  return QFileDialog::eventFilter(obj, event);
+}

+ 58 - 0
Libs/Widgets/ctkFileDialog.h

@@ -0,0 +1,58 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkFileDialog_h
+#define __ctkFileDialog_h
+
+// Qt includes
+#include <QFileDialog>
+
+// CTK includes
+#include <ctkPimpl.h>
+#include "CTKWidgetsExport.h"
+
+class ctkFileDialogPrivate;
+
+class CTK_WIDGETS_EXPORT ctkFileDialog : public QFileDialog
+{
+  Q_OBJECT
+
+public:
+  // Superclass typedef
+  typedef QFileDialog Superclass;
+  // Constructors
+  explicit ctkFileDialog(QWidget *parent = 0,
+              const QString &caption = QString(),
+              const QString &directory = QString(),
+              const QString &filter = QString());
+  virtual ~ctkFileDialog();
+
+  void setBottomWidget(QWidget* widget, const QString& label=QString());
+  QWidget* bottomWidget()const;
+
+  bool eventFilter(QObject *obj, QEvent *event);
+public slots:
+  void setAcceptButtonEnable(bool enable);
+
+private:
+  CTK_DECLARE_PRIVATE(ctkFileDialog);
+};
+
+#endif