123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /*=========================================================================
- Library: CTK
- Copyright (c) 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.apache.org/licenses/LICENSE-2.0.txt
- 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 <QListView>
- #include <QPushButton>
- // CTK includes
- #include "ctkFileDialog.h"
- //------------------------------------------------------------------------------
- class ctkFileDialogPrivate
- {
- Q_DECLARE_PUBLIC(ctkFileDialog);
- protected:
- ctkFileDialog* const q_ptr;
- public:
- ctkFileDialogPrivate(ctkFileDialog& object);
- void init();
- QPushButton* acceptButton()const;
- QListView* listView()const;
- bool AcceptButtonEnable;
- bool AcceptButtonState;
- bool IgnoreEvent;
- };
- //------------------------------------------------------------------------------
- ctkFileDialogPrivate::ctkFileDialogPrivate(ctkFileDialog& object)
- :q_ptr(&object)
- {
- this->IgnoreEvent = false;
- this->AcceptButtonEnable = true;
- this->AcceptButtonState = true;
- }
- //------------------------------------------------------------------------------
- void ctkFileDialogPrivate::init()
- {
- Q_Q(ctkFileDialog);
- QPushButton* button = this->acceptButton();
- Q_ASSERT(button);
- this->AcceptButtonState =
- button->isEnabledTo(qobject_cast<QWidget*>(button->parent()));
- // TODO: catching the event of the enable state is not enough, if the user
- // double click on the file, the dialog will be accepted, that event should
- // be intercepted as well
- button->installEventFilter(q);
- QObject::connect(this->listView()->selectionModel(),
- SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- q, SLOT(onSelectionChanged()));
- }
- //------------------------------------------------------------------------------
- QPushButton* ctkFileDialogPrivate::acceptButton()const
- {
- Q_Q(const ctkFileDialog);
- QDialogButtonBox* buttonBox = q->findChild<QDialogButtonBox*>();
- Q_ASSERT(buttonBox);
- QDialogButtonBox::StandardButton button =
- (q->acceptMode() == QFileDialog::AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
- return buttonBox->button(button);
- }
- //------------------------------------------------------------------------------
- QListView* ctkFileDialogPrivate::listView()const
- {
- Q_Q(const ctkFileDialog);
- QListView* listView= q->findChild<QListView*>("listView");
- Q_ASSERT(listView);
- return listView;
- }
- //------------------------------------------------------------------------------
- ctkFileDialog::ctkFileDialog(QWidget *parentWidget,
- const QString &caption,
- const QString &directory,
- const QString &filter)
- :QFileDialog(parentWidget, caption, directory, filter)
- , d_ptr(new ctkFileDialogPrivate(*this))
- {
- Q_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();
- // remove the old widget from the layout if any
- 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);
- }
- // The dialog button box is no longer spanned on 2 rows but on 3 rows if
- // there is a "bottom widget"
- QDialogButtonBox* buttonBox = this->findChild<QDialogButtonBox*>();
- Q_ASSERT(buttonBox);
- gridLayout->removeWidget(buttonBox);
- gridLayout->addWidget(buttonBox, 2, 2, widget ? 3 : 2, 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)
- {
- Q_D(ctkFileDialog);
- d->AcceptButtonEnable = enable;
- d->IgnoreEvent = true;
- d->acceptButton()->setEnabled(d->AcceptButtonEnable && d->AcceptButtonState);
- d->IgnoreEvent = false;
- }
- //------------------------------------------------------------------------------
- bool ctkFileDialog::eventFilter(QObject *obj, QEvent *event)
- {
- Q_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);
- }
- //------------------------------------------------------------------------------
- void ctkFileDialog::onSelectionChanged()
- {
- emit this->fileSelectionChanged(this->selectedFiles());
- }
|