Salome HOME
Add file dialog options in QtxPathEdit
[modules/gui.git] / src / Qtx / QtxPathEdit.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File:      QtxPathEdit.cxx
21 // Author:    Sergey TELKOV
22 //
23 #include "QtxPathEdit.h"
24
25 #include <QApplication>
26 #include <QLayout>
27 #include <QDirModel>
28 #include <QLineEdit>
29 #include <QCompleter>
30 #include <QKeyEvent>
31 #include <QToolButton>
32 #include <QRegExpValidator>
33
34 static const char* browse_icon[] = {
35 "16 16 5 1",
36 "  c none",
37 ". c #ffff00",
38 "# c #848200",
39 "a c #ffffff",
40 "b c #000000",
41 "                ",
42 "          bbb   ",
43 "         b   b b",
44 "              bb",
45 "  bbb        bbb",
46 " ba.abbbbbbb    ",
47 " b.a.a.a.a.b    ",
48 " ba.a.a.a.ab    ",
49 " b.a.abbbbbbbbbb",
50 " ba.ab#########b",
51 " b.ab#########b ",
52 " bab#########b  ",
53 " bb#########b   ",
54 " bbbbbbbbbbb    ",
55 "                ",
56 "                "
57 };
58
59 /*!
60   \class QtxPathEdit
61   \brief The QtxPathEdit class represents a widget for file or directory
62   path preference items editing.
63
64   The path preference item is represented as the line edit box for the 
65   direct path editing and small button clicking on which invokes browse
66   dialog box. The widget can be used in different modes: "Open File", 
67   "Save File", "Select Directory". The mode defines the type of the
68   standard browse dialog box which is invoked on the button clicking.
69
70   Initial path value can be set with setPath() method. Chosen path
71   can be retrieved with the path() method. The widget mode can be set 
72   with setPathType() and retrieved with pathType() method.
73
74   In addition, file/direcrory filters (wildcards) can be set with the
75   setPathFilter() method and retrieved with pathFilter() method.
76 */
77
78 /*!
79   \brief Constructor
80   \param type widget mode (Qtx::PathType)
81   \param parent parent widget
82   \param browse if \c true, automatically finish editing of file path when
83                 user presses OK in "Select File/Directory" dialog box
84   \sa pathType(), setPathType()
85 */
86 QtxPathEdit::QtxPathEdit( const Qtx::PathType type, QWidget* parent, bool browse )
87 : QFrame( parent ),
88   myType( type ),
89   myBrowse ( browse )
90 {
91   initialize();
92 }
93
94 /*!
95   \brief Constructor
96
97   Qtx::PT_OpenFile mode is used by default.
98
99   \param parent parent widget
100   \param browse if \c true, automatically finish editing of file path when
101                 user presses OK in "Select File/Directory" dialog box
102   \sa pathType(), setPathType()
103 */
104 QtxPathEdit::QtxPathEdit( QWidget* parent, bool browse )
105 : QFrame( parent ),
106   myType( Qtx::PT_OpenFile ),
107   myBrowse ( browse )
108 {
109   initialize();
110 }
111
112 /*!
113   \brief Destructor
114 */
115 QtxPathEdit::~QtxPathEdit()
116 {
117 }
118
119 /*!
120   \brief Get widget mode.
121   \return currently used widget mode (Qtx::PathType)
122   \sa setPathType()
123 */
124 Qtx::PathType QtxPathEdit::pathType() const
125 {
126   return myType;
127 }
128
129 /*!
130   \brief Set widget mode.
131   \param type new widget mode (Qtx::PathType)
132   \sa pathType()
133 */
134 void QtxPathEdit::setPathType( const Qtx::PathType type )
135 {
136   if ( myType == type )
137     return;
138
139   myType = type;
140   updateState();
141 }
142
143 /*!
144   \brief Get currently selected path.
145   \return file or directory path entered by the user
146   \sa setPath()
147 */
148 QString QtxPathEdit::path() const
149 {
150   return myPath->text();
151 }
152
153 /*!
154   \brief Set path.
155   \param txt file or directory path 
156   \sa path()
157 */
158 void QtxPathEdit::setPath( const QString& txt )
159 {
160   myPath->setText( txt );
161 }
162
163 /*!
164   \brief Get currently used path filters.
165   \return file or directory path filters
166   \sa setPathFilter()
167 */
168 QString QtxPathEdit::pathFilter() const
169 {
170   return myFilter;
171 }
172
173 /*!
174   \brief Set path filters.
175   \param f new file or directory path filters
176   \sa pathFilter()
177 */
178 void QtxPathEdit::setPathFilter( const QString& f )
179 {
180   if ( myFilter == f )
181     return;
182
183   myFilter = f;
184   updateState();
185 }
186
187 /*!
188   \brief Set path file dialog options.
189   \param f new file or directory path options
190   \sa pathOptions()
191 */
192 void QtxPathEdit::setPathOptions(const QFileDialog::Options options)
193 {
194   if ( myOptions == options )
195     return;
196
197   myOptions = options;
198 }
199
200 /*!
201   \brief Get currently used path options.
202   \return file or directory path options
203   \sa setPathOptions()
204 */
205 QFileDialog::Options QtxPathEdit::pathOptions() const
206 {
207   return myOptions;
208 }
209
210
211 /*!
212   \brief Called when user clicks "Browse" button. 
213
214   Invokes standard browsng dialog box depending on the used widget mode.
215
216   \param on (not used)
217   \sa mode(), setMode()
218 */
219 void QtxPathEdit::onBrowse( bool /*on*/ )
220 {
221   QString path;
222   QString initial = QFileInfo( Qtx::makeEnvVarSubst( myPath->text() ) ).filePath();
223   switch ( pathType() )
224   {
225   case Qtx::PT_OpenFile:
226     path = QFileDialog::getOpenFileName( myPath, QString(), initial, pathFilter(), nullptr, pathOptions() );
227     break;
228   case Qtx::PT_SaveFile:
229     path = QFileDialog::getSaveFileName( myPath, QString(), initial, pathFilter(), nullptr, pathOptions() );
230     break;
231   case Qtx::PT_Directory:
232     path = QFileDialog::getExistingDirectory( myPath, QString(), initial, pathOptions() );
233     break;
234   }
235
236   if ( !path.isEmpty() )
237     myPath->setText( QDir::toNativeSeparators( path ) ); 
238
239   myPath->setFocus();
240
241   if ( !path.isEmpty() && myBrowse )
242     QApplication::postEvent( myPath, new QKeyEvent( QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier ) );
243 }
244
245 /*!
246   \brief Get internal line edit widget.
247   \return line edit box widget
248 */
249 QLineEdit* QtxPathEdit::lineEdit() const
250 {
251   return myPath;
252 }
253
254 /*!
255   \brief Perform internal widget intialization.
256 */
257 void QtxPathEdit::initialize()
258 {
259   QHBoxLayout* base = new QHBoxLayout( this );
260   base->setMargin( 0 );
261   base->setSpacing( 5 );
262
263   base->addWidget( myPath = new QLineEdit( this ) );
264   myPath->setValidator( new QRegExpValidator( QRegExp( "^([\\$]|[\\%]|[\\w/]{2}|[A-Z]:)[^:;\\*\\?]*[\\w\\\\/\\.]$" ), myPath ) );
265
266   QToolButton* browse = new QToolButton( this );
267   browse->setIcon( QPixmap( browse_icon ) );
268   base->addWidget( browse );
269
270   connect( browse, SIGNAL( clicked( bool ) ), this, SLOT( onBrowse( bool ) ) );
271
272   setFocusProxy( myPath );
273
274   updateState();
275 }
276
277 /*!
278   \brief Update widget state.
279 */
280 void QtxPathEdit::updateState()
281 {
282   myPath->setCompleter( Qtx::pathCompleter( pathType(), pathFilter() ) );
283 }