1 /*=========================================================================
2 
3   Library:   CTK
4 
5   Copyright (c) Kitware Inc.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11       http://www.apache.org/licenses/LICENSE-2.0.txt
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 =========================================================================*/
20 
21 // Qt includes
22 #include <QAbstractItemView>
23 #include <QApplication>
24 #include <QComboBox>
25 #include <QCompleter>
26 #include <QDebug>
27 #include <QDirModel>
28 #include <QFileDialog>
29 #include <QHBoxLayout>
30 #include <QLineEdit>
31 #include <QRegExp>
32 #include <QRegExpValidator>
33 #include <QSettings>
34 #include <QStyleOptionComboBox>
35 #include <QToolButton>
36 
37 // CTK includes
38 #include "ctkPathLineEdit.h"
39 #include "ctkUtils.h"
40 
41 //-----------------------------------------------------------------------------
42 class ctkPathLineEditPrivate
43 {
44   Q_DECLARE_PUBLIC(ctkPathLineEdit);
45 
46 protected:
47   ctkPathLineEdit* const q_ptr;
48 
49 public:
50   ctkPathLineEditPrivate(ctkPathLineEdit& object);
51   void init();
52   QSize recomputeSizeHint(QSize& sh)const;
53   void updateFilter();
54 
55   void adjustPathLineEditSize();
56 
57   void _q_recomputeCompleterPopupSize();
58 
59   void createPathLineEditWidget(bool useComboBox);
60   QString settingKey()const;
61 
62   QLineEdit*            LineEdit;
63   QComboBox*            ComboBox;
64   QToolButton*          BrowseButton;       //!< "..." button
65 
66   int                   MinimumContentsLength;
67   ctkPathLineEdit::SizeAdjustPolicy SizeAdjustPolicy;
68 
69   QString               Label;              //!< used in file dialogs
70   QStringList           NameFilters;        //!< Regular expression (in wildcard mode) used to help the user to complete the line
71   QDir::Filters         Filters;            //!< Type of path (file, dir...)
72 #ifdef USE_QFILEDIALOG_OPTIONS
73   QFileDialog::Options DialogOptions;
74 #else
75   ctkPathLineEdit::Options DialogOptions;
76 #endif
77 
78   bool                  HasValidInput;      //!< boolean that stores the old state of valid input
79   QString               SettingKey;
80 
81   static QString        sCurrentDirectory;   //!< Content the last value of the current directory
82   static int            sMaxHistory;     //!< Size of the history, if the history is full and a new value is added, the oldest value is dropped
83 
84   mutable QSize SizeHint;
85   mutable QSize MinimumSizeHint;
86 };
87 
88 QString ctkPathLineEditPrivate::sCurrentDirectory = "";
89 int ctkPathLineEditPrivate::sMaxHistory = 5;
90 
91 //-----------------------------------------------------------------------------
ctkPathLineEditPrivate(ctkPathLineEdit & object)92 ctkPathLineEditPrivate::ctkPathLineEditPrivate(ctkPathLineEdit& object)
93   : q_ptr(&object)
94   , LineEdit(0)
95   , ComboBox(0)
96   , BrowseButton(0)
97   , MinimumContentsLength(0)
98   , SizeAdjustPolicy(ctkPathLineEdit::AdjustToContentsOnFirstShow)
99   , Filters(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Readable)
100   , HasValidInput(false)
101 {
102 }
103 
104 //-----------------------------------------------------------------------------
init()105 void ctkPathLineEditPrivate::init()
106 {
107   Q_Q(ctkPathLineEdit);
108 
109   QHBoxLayout* layout = new QHBoxLayout(q);
110   layout->setContentsMargins(0,0,0,0);
111   layout->setSpacing(0); // no space between the combobx and button
112 
113   this->createPathLineEditWidget(true);
114 
115   this->BrowseButton = new QToolButton(q);
116   this->BrowseButton->setText("...");
117   // Don't vertically stretch the path line edit unnecessary
118   this->BrowseButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored));
119   this->BrowseButton->setToolTip(ctkPathLineEdit::tr("Open a dialog"));
120 
121   QObject::connect(this->BrowseButton,SIGNAL(clicked()),
122                    q, SLOT(browse()));
123 
124   layout->addWidget(this->BrowseButton);
125 
126   q->setSizePolicy(QSizePolicy(
127                      QSizePolicy::Expanding, QSizePolicy::Fixed,
128                      QSizePolicy::LineEdit));
129 }
130 
131 //------------------------------------------------------------------------------
createPathLineEditWidget(bool useComboBox)132 void ctkPathLineEditPrivate::createPathLineEditWidget(bool useComboBox)
133 {
134   Q_Q(ctkPathLineEdit);
135 
136   QString path = q->currentPath();
137 
138   if (useComboBox)
139     {
140     this->ComboBox = new QComboBox(q);
141     this->ComboBox->setEditable(true);
142     this->ComboBox->setInsertPolicy(QComboBox::NoInsert);
143     this->LineEdit = this->ComboBox->lineEdit();
144     }
145   else
146     {
147     this->ComboBox = 0;
148     this->LineEdit = new QLineEdit(q);
149     }
150 
151   if (q->layout() && q->layout()->itemAt(0))
152     {
153     delete q->layout()->itemAt(0)->widget();
154     }
155   qobject_cast<QHBoxLayout*>(q->layout())->insertWidget(
156     0,
157     this->ComboBox ? qobject_cast<QWidget*>(this->ComboBox) :
158     qobject_cast<QWidget*>(this->LineEdit));
159 
160   this->updateFilter();
161   q->retrieveHistory();
162   q->setCurrentPath(path);
163 
164   QObject::connect(this->LineEdit, SIGNAL(textChanged(QString)),
165                    q, SLOT(setCurrentDirectory(QString)));
166   QObject::connect(this->LineEdit, SIGNAL(textChanged(QString)),
167                    q, SLOT(updateHasValidInput()));
168   q->updateGeometry();
169 }
170 
171 //------------------------------------------------------------------------------
recomputeSizeHint(QSize & sh) const172 QSize ctkPathLineEditPrivate::recomputeSizeHint(QSize& sh)const
173 {
174   Q_Q(const ctkPathLineEdit);
175   if (!sh.isValid())
176     {
177     int frame = 0;
178     if (this->ComboBox)
179       {
180       QStyleOptionComboBox option;
181       int arrowWidth = this->ComboBox->style()->subControlRect(
182             QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxArrow, this->ComboBox).width()
183           + (this->ComboBox->hasFrame() ? 2 : 0);
184       frame = 2 * (this->ComboBox->hasFrame() ? 3 : 0)
185           + arrowWidth
186           + 1; // for mac style, not sure why
187       }
188     else
189       {
190       QStyleOptionFrame option;
191       int frameWidth = this->LineEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, q);
192       int horizontalMargin = 2; // QLineEditPrivate::horizontalMargin
193       // See QLineEdit::sizeHint
194       frame = 2 * frameWidth
195           + this->LineEdit->textMargins().left()
196           + this->LineEdit->textMargins().right()
197           + this->LineEdit->contentsMargins().left()
198           + this->LineEdit->contentsMargins().right()
199           + 2 * horizontalMargin;
200       }
201     int browseWidth = 0;
202     if (q->showBrowseButton())
203       {
204       browseWidth = this->BrowseButton->minimumSizeHint().width();
205       }
206 
207     // text width
208     int textWidth = 0;
209     if (&sh == &this->SizeHint || this->MinimumContentsLength == 0)
210       {
211       switch (SizeAdjustPolicy)
212         {
213         case ctkPathLineEdit::AdjustToContents:
214         case ctkPathLineEdit::AdjustToContentsOnFirstShow:
215           if (this->LineEdit->text().isEmpty())
216             {
217             textWidth = 7 * this->LineEdit->fontMetrics().width(QLatin1Char('x'));
218             }
219           else
220             {
221             textWidth = this->LineEdit->fontMetrics().boundingRect(this->LineEdit->text()).width() + 8;
222             }
223           break;
224         case QComboBox::AdjustToMinimumContentsLength:
225         default:
226           ;
227         }
228       }
229 
230     if (this->MinimumContentsLength > 0)
231       {
232       textWidth = qMax(textWidth, this->MinimumContentsLength * this->LineEdit->fontMetrics().width(QLatin1Char('X')));
233       }
234 
235     int height = (this->ComboBox ? this->ComboBox->minimumSizeHint() :
236                                    this->LineEdit->minimumSizeHint()).height();
237     sh.rwidth() = frame + textWidth + browseWidth;
238     sh.rheight() = height;
239   }
240   return sh.expandedTo(QApplication::globalStrut());
241 }
242 
243 //-----------------------------------------------------------------------------
updateFilter()244 void ctkPathLineEditPrivate::updateFilter()
245 {
246   Q_Q(ctkPathLineEdit);
247   // help completion for the QComboBox::QLineEdit
248   QCompleter *newCompleter = new QCompleter(q);
249   newCompleter->setModel(new QDirModel(
250                            ctk::nameFiltersToExtensions(this->NameFilters),
251                            this->Filters | QDir::NoDotAndDotDot | QDir::AllDirs,
252                            QDir::Name|QDir::DirsLast, newCompleter));
253   this->LineEdit->setCompleter(newCompleter);
254 
255   QObject::connect(this->LineEdit->completer()->completionModel(), SIGNAL(layoutChanged()),
256                    q, SLOT(_q_recomputeCompleterPopupSize()));
257 
258   // don't accept invalid path
259   QRegExpValidator* validator = new QRegExpValidator(
260     ctk::nameFiltersToRegExp(this->NameFilters), q);
261   this->LineEdit->setValidator(validator);
262 }
263 
264 //-----------------------------------------------------------------------------
adjustPathLineEditSize()265 void ctkPathLineEditPrivate::adjustPathLineEditSize()
266 {
267   Q_Q(ctkPathLineEdit);
268   if (q->sizeAdjustPolicy() == ctkPathLineEdit::AdjustToContents)
269     {
270     q->updateGeometry();
271     q->adjustSize();
272     q->update();
273     }
274 }
275 
276 //-----------------------------------------------------------------------------
_q_recomputeCompleterPopupSize()277 void ctkPathLineEditPrivate::_q_recomputeCompleterPopupSize()
278 {
279   QSize lineEditSize = this->LineEdit->size();
280 
281   QAbstractItemView* view = this->LineEdit->completer()->popup();
282   const QFontMetrics& fm = view->fontMetrics();
283 
284   int iconWidth = 0;
285   int textWidth = 0;
286 
287   QStyleOptionFrame option;
288   int frameWidth = view->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, view);
289   int frame = 2 * frameWidth
290       + view->contentsMargins().left()
291       + view->contentsMargins().right();
292 
293   QAbstractItemModel* model = this->LineEdit->completer()->completionModel();
294   for (int i = 0; i < model->rowCount(); ++i)
295     {
296     QVariant icon = model->data(model->index(i, 0), Qt::DecorationRole);
297     if (icon.isValid() && icon.canConvert<QIcon>())
298       {
299       iconWidth = qMax(iconWidth, icon.value<QIcon>().availableSizes().front().width() + 4);
300       }
301     textWidth = qMax(textWidth, fm.boundingRect(model->data(model->index(i, 0)).toString()).width());
302     }
303 
304   view->setMinimumWidth(qMax(frame + iconWidth + textWidth, lineEditSize.width()));
305 }
306 
307 //-----------------------------------------------------------------------------
settingKey() const308 QString ctkPathLineEditPrivate::settingKey()const
309 {
310   Q_Q(const ctkPathLineEdit);
311   return QString("ctkPathLineEdit/") +
312     (this->SettingKey.isEmpty() ? q->objectName() : this->SettingKey);
313 }
314 
315 //-----------------------------------------------------------------------------
ctkPathLineEdit(QWidget * parentWidget)316 ctkPathLineEdit::ctkPathLineEdit(QWidget *parentWidget)
317   : QWidget(parentWidget)
318   , d_ptr(new ctkPathLineEditPrivate(*this))
319 {
320   Q_D(ctkPathLineEdit);
321   d->init();
322 
323   this->setNameFilters(nameFilters());
324   this->setFilters(filters());
325 }
326 
327 //-----------------------------------------------------------------------------
ctkPathLineEdit(const QString & label,const QStringList & nameFilters,Filters filters,QWidget * parentWidget)328 ctkPathLineEdit::ctkPathLineEdit(const QString& label,
329                                  const QStringList& nameFilters,
330                                  Filters filters,
331                                  QWidget *parentWidget)
332   : QWidget(parentWidget)
333   , d_ptr(new ctkPathLineEditPrivate(*this))
334 {
335   Q_D(ctkPathLineEdit);
336   d->init();
337 
338   this->setLabel(label);
339   this->setNameFilters(nameFilters);
340   this->setFilters(filters);
341 }
342 
343 //-----------------------------------------------------------------------------
~ctkPathLineEdit()344 ctkPathLineEdit::~ctkPathLineEdit()
345 {
346 }
347 
348 //-----------------------------------------------------------------------------
setLabel(const QString & label)349 void ctkPathLineEdit::setLabel(const QString &label)
350 {
351   Q_D(ctkPathLineEdit);
352   d->Label = label;
353 }
354 
355 //-----------------------------------------------------------------------------
label() const356 const QString& ctkPathLineEdit::label()const
357 {
358   Q_D(const ctkPathLineEdit);
359   return d->Label;
360 }
361 
362 //-----------------------------------------------------------------------------
setNameFilters(const QStringList & nameFilters)363 void ctkPathLineEdit::setNameFilters(const QStringList &nameFilters)
364 {
365   Q_D(ctkPathLineEdit);
366   d->NameFilters = nameFilters;
367   d->updateFilter();
368 }
369 
370 //-----------------------------------------------------------------------------
nameFilters() const371 const QStringList& ctkPathLineEdit::nameFilters()const
372 {
373   Q_D(const ctkPathLineEdit);
374   return d->NameFilters;
375 }
376 
377 //-----------------------------------------------------------------------------
setFilters(const Filters & filters)378 void ctkPathLineEdit::setFilters(const Filters &filters)
379 {
380   Q_D(ctkPathLineEdit);
381   d->Filters = QFlags<QDir::Filter>(static_cast<int>(filters));
382   d->updateFilter();
383 }
384 
385 //-----------------------------------------------------------------------------
filters() const386 ctkPathLineEdit::Filters ctkPathLineEdit::filters()const
387 {
388   Q_D(const ctkPathLineEdit);
389   return QFlags<ctkPathLineEdit::Filter>(static_cast<int>(d->Filters));
390 }
391 
392 //-----------------------------------------------------------------------------
393 #ifdef USE_QFILEDIALOG_OPTIONS
setOptions(const QFileDialog::Options & dialogOptions)394 void ctkPathLineEdit::setOptions(const QFileDialog::Options& dialogOptions)
395 #else
396 void ctkPathLineEdit::setOptions(const Options& dialogOptions)
397 #endif
398 {
399   Q_D(ctkPathLineEdit);
400   d->DialogOptions = dialogOptions;
401 }
402 
403 //-----------------------------------------------------------------------------
404 #ifdef USE_QFILEDIALOG_OPTIONS
options() const405 const QFileDialog::Options& ctkPathLineEdit::options()const
406 #else
407 const ctkPathLineEdit::Options& ctkPathLineEdit::options()const
408 #endif
409 {
410   Q_D(const ctkPathLineEdit);
411   return d->DialogOptions;
412 }
413 
414 //-----------------------------------------------------------------------------
browse()415 void ctkPathLineEdit::browse()
416 {
417   Q_D(ctkPathLineEdit);
418   QString path = "";
419   if ( d->Filters & QDir::Files ) //file
420     {
421     if ( d->Filters & QDir::Writable) // load or save
422       {
423       path = QFileDialog::getSaveFileName(
424 	this,
425         tr("Select a file to save "),
426         this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory :
427 	                                this->currentPath(),
428 	d->NameFilters.join(";;"),
429 	0,
430 #ifdef USE_QFILEDIALOG_OPTIONS
431       d->DialogOptions);
432 #else
433       QFlags<QFileDialog::Option>(int(d->DialogOptions)));
434 #endif
435       }
436     else
437       {
438       path = QFileDialog::getOpenFileName(
439         this,
440         QString("Open a file"),
441         this->currentPath().isEmpty()? ctkPathLineEditPrivate::sCurrentDirectory :
442 	                               this->currentPath(),
443         d->NameFilters.join(";;"),
444 	0,
445 #ifdef USE_QFILEDIALOG_OPTIONS
446       d->DialogOptions);
447 #else
448       QFlags<QFileDialog::Option>(int(d->DialogOptions)));
449 #endif
450       }
451     }
452   else //directory
453     {
454     path = QFileDialog::getExistingDirectory(
455       this,
456       QString("Select a directory..."),
457       this->currentPath().isEmpty() ? ctkPathLineEditPrivate::sCurrentDirectory :
458                                       this->currentPath(),
459 #ifdef USE_QFILEDIALOG_OPTIONS
460       d->DialogOptions);
461 #else
462       QFlags<QFileDialog::Option>(int(d->DialogOptions)));
463 #endif
464     }
465   if (path.isEmpty())
466     {
467     return;
468     }
469   this->setCurrentPath(path);
470 }
471 
472 //-----------------------------------------------------------------------------
retrieveHistory()473 void ctkPathLineEdit::retrieveHistory()
474 {
475   Q_D(ctkPathLineEdit);
476   if (d->ComboBox == 0)
477     {
478     return;
479     }
480   QString path = this->currentPath();
481   bool wasBlocking = this->blockSignals(true);
482   d->ComboBox->clear();
483   // fill the combobox using the QSettings
484   QSettings settings;
485   QString key = d->settingKey();
486   const QStringList history = settings.value(key).toStringList();
487   foreach(const QString& path, history)
488     {
489     d->ComboBox->addItem(path);
490     if (d->ComboBox->count() >= ctkPathLineEditPrivate::sMaxHistory)
491       {
492       break;
493       }
494     }
495   // Restore path or select the most recent file location if none set.
496   if (path.isEmpty())
497     {
498     this->blockSignals(wasBlocking);
499     d->ComboBox->setCurrentIndex(0);
500     }
501   else
502     {
503     this->setCurrentPath(path);
504     this->blockSignals(wasBlocking);
505     }
506 }
507 
508 //-----------------------------------------------------------------------------
addCurrentPathToHistory()509 void ctkPathLineEdit::addCurrentPathToHistory()
510 {
511   Q_D(ctkPathLineEdit);
512   if (d->ComboBox == 0 ||
513       this->currentPath().isEmpty())
514     {
515     return;
516     }
517   QSettings settings;
518   //keep the same values, add the current value
519   //if more than m_MaxHistory entrees, drop the oldest.
520   QString key = d->settingKey();
521   QStringList history = settings.value(key).toStringList();
522   QString pathToAdd = this->currentPath();
523   if (history.contains(pathToAdd))
524     {
525     history.removeAll(pathToAdd);
526     }
527   history.push_front(pathToAdd);
528   settings.setValue(key, history);
529   // don't fire intermediate events.
530   bool wasBlocking = d->ComboBox->blockSignals(false);
531   int index = d->ComboBox->findText(this->currentPath());
532   if (index >= 0)
533     {
534     d->ComboBox->removeItem(index);
535     }
536   while (d->ComboBox->count() >= ctkPathLineEditPrivate::sMaxHistory)
537     {
538     d->ComboBox->removeItem(d->ComboBox->count() - 1);
539     }
540   d->ComboBox->insertItem(0, pathToAdd);
541   d->ComboBox->setCurrentIndex(0);
542   d->ComboBox->blockSignals(wasBlocking);
543 }
544 
545 //------------------------------------------------------------------------------
setCurrentFileExtension(const QString & extension)546 void ctkPathLineEdit::setCurrentFileExtension(const QString& extension)
547 {
548   QString filename = this->currentPath();
549   QFileInfo fileInfo(filename);
550 
551   if (!fileInfo.suffix().isEmpty())
552     {
553     filename.replace(fileInfo.suffix(), extension);
554     }
555   else
556     {
557     filename.append(QString(".") + extension);
558     }
559   this->setCurrentPath(filename);
560 }
561 
562 //------------------------------------------------------------------------------
comboBox() const563 QComboBox* ctkPathLineEdit::comboBox() const
564 {
565   Q_D(const ctkPathLineEdit);
566   return d->ComboBox;
567 }
568 
569 //------------------------------------------------------------------------------
currentPath() const570 QString ctkPathLineEdit::currentPath()const
571 {
572   Q_D(const ctkPathLineEdit);
573   return d->LineEdit ? d->LineEdit->text() : QString();
574 }
575 
576 //------------------------------------------------------------------------------
setCurrentPath(const QString & path)577 void ctkPathLineEdit::setCurrentPath(const QString& path)
578 {
579   Q_D(ctkPathLineEdit);
580   d->LineEdit->setText(path);
581 }
582 
583 //------------------------------------------------------------------------------
setCurrentDirectory(const QString & directory)584 void ctkPathLineEdit::setCurrentDirectory(const QString& directory)
585 {
586   ctkPathLineEditPrivate::sCurrentDirectory = directory;
587 }
588 
589 //------------------------------------------------------------------------------
updateHasValidInput()590 void ctkPathLineEdit::updateHasValidInput()
591 {
592   Q_D(ctkPathLineEdit);
593 
594   bool oldHasValidInput = d->HasValidInput;
595   d->HasValidInput = d->LineEdit->hasAcceptableInput();
596   if (d->HasValidInput)
597     {
598     QFileInfo fileInfo(this->currentPath());
599     ctkPathLineEditPrivate::sCurrentDirectory =
600       fileInfo.isFile() ? fileInfo.absolutePath() : fileInfo.absoluteFilePath();
601     emit currentPathChanged(this->currentPath());
602     }
603   if (d->HasValidInput != oldHasValidInput)
604     {
605     emit validInputChanged(d->HasValidInput);
606     }
607 
608   if (d->SizeAdjustPolicy == AdjustToContents)
609     {
610     d->SizeHint = QSize();
611     d->adjustPathLineEditSize();
612     this->updateGeometry();
613     }
614 }
615 
616 //------------------------------------------------------------------------------
settingKey() const617 QString ctkPathLineEdit::settingKey()const
618 {
619   Q_D(const ctkPathLineEdit);
620   return d->SettingKey;
621 }
622 
623 //------------------------------------------------------------------------------
setSettingKey(const QString & key)624 void ctkPathLineEdit::setSettingKey(const QString& key)
625 {
626   Q_D(ctkPathLineEdit);
627   d->SettingKey = key;
628   this->retrieveHistory();
629 }
630 
631 //------------------------------------------------------------------------------
showBrowseButton() const632 bool ctkPathLineEdit::showBrowseButton()const
633 {
634   Q_D(const ctkPathLineEdit);
635   return d->BrowseButton->isVisibleTo(const_cast<ctkPathLineEdit*>(this));
636 }
637 
638 //------------------------------------------------------------------------------
setShowBrowseButton(bool visible)639 void ctkPathLineEdit::setShowBrowseButton(bool visible)
640 {
641   Q_D(ctkPathLineEdit);
642   d->BrowseButton->setVisible(visible);
643 }
644 
645 //------------------------------------------------------------------------------
showHistoryButton() const646 bool ctkPathLineEdit::showHistoryButton()const
647 {
648   Q_D(const ctkPathLineEdit);
649   return d->ComboBox ? true: false;
650 }
651 
652 //------------------------------------------------------------------------------
setShowHistoryButton(bool visible)653 void ctkPathLineEdit::setShowHistoryButton(bool visible)
654 {
655   Q_D(ctkPathLineEdit);
656   d->createPathLineEditWidget(visible);
657 }
658 
659 //------------------------------------------------------------------------------
sizeAdjustPolicy() const660 ctkPathLineEdit::SizeAdjustPolicy ctkPathLineEdit::sizeAdjustPolicy() const
661 {
662   Q_D(const ctkPathLineEdit);
663   return d->SizeAdjustPolicy;
664 }
665 
666 //------------------------------------------------------------------------------
setSizeAdjustPolicy(ctkPathLineEdit::SizeAdjustPolicy policy)667 void ctkPathLineEdit::setSizeAdjustPolicy(ctkPathLineEdit::SizeAdjustPolicy policy)
668 {
669   Q_D(ctkPathLineEdit);
670   if (policy == d->SizeAdjustPolicy)
671     return;
672 
673   d->SizeAdjustPolicy = policy;
674   d->SizeHint = QSize();
675   d->adjustPathLineEditSize();
676   this->updateGeometry();
677 }
678 
679 //------------------------------------------------------------------------------
minimumContentsLength() const680 int ctkPathLineEdit::minimumContentsLength()const
681 {
682   Q_D(const ctkPathLineEdit);
683   return d->MinimumContentsLength;
684 }
685 
686 //------------------------------------------------------------------------------
setMinimumContentsLength(int length)687 void ctkPathLineEdit::setMinimumContentsLength(int length)
688 {
689   Q_D(ctkPathLineEdit);
690   if (d->MinimumContentsLength == length || length < 0) return;
691 
692   d->MinimumContentsLength = length;
693 
694   if (d->SizeAdjustPolicy == AdjustToContents ||
695       d->SizeAdjustPolicy == AdjustToMinimumContentsLength)
696     {
697     d->SizeHint = QSize();
698     d->adjustPathLineEditSize();
699     this->updateGeometry();
700     }
701 }
702 
703 //------------------------------------------------------------------------------
minimumSizeHint() const704 QSize ctkPathLineEdit::minimumSizeHint()const
705 {
706   Q_D(const ctkPathLineEdit);
707   return d->recomputeSizeHint(d->MinimumSizeHint);
708 }
709 
710 //------------------------------------------------------------------------------
sizeHint() const711 QSize ctkPathLineEdit::sizeHint()const
712 {
713   Q_D(const ctkPathLineEdit);
714   return d->recomputeSizeHint(d->SizeHint);
715 }
716 
717 #include "moc_ctkPathLineEdit.cpp"
718