kexi

KexiStartupFileDialog.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2005 Jaroslaw Staniek <js@iidea.pl>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "KexiStartupFileDialog.h"
21
22#include <kexidb/driver.h>
23#include <core/kexi.h>
24#include <kexiutils/utils.h>
25
26#include <tqlayout.h>
27#include <tqobjectlist.h>
28#include <tqpushbutton.h>
29#include <tqapplication.h>
30
31#include <tdemessagebox.h>
32#include <tdelocale.h>
33#include <kdebug.h>
34#include <kmimetype.h>
35#include <tdefile.h>
36#include <kurlcombobox.h>
37
38KexiStartupFileDialog::KexiStartupFileDialog(
39 const TQString& startDirOrVariable, int mode,
40 TQWidget *parent, const char *name)
41 : KexiStartupFileDialogBase(startDirOrVariable, "", parent, name, 0)
42 , m_confirmOverwrites(true)
43 , m_filtersUpdated(false)
44{
45 setSizePolicy(TQSizePolicy::Minimum,TQSizePolicy::Minimum);
46 setMode( mode );
47
48 TQPoint point( 0, 0 );
49 reparent( parentWidget(), point );
50
51 if (layout())
52 layout()->setMargin(0);
53 setMinimumHeight(100);
54 setSizeGripEnabled ( false );
55
56 //dirty hack to customize filedialog view:
57 {
58 TQObjectList *l = queryList( "TQPushButton" );
59 TQObjectListIt it( *l );
60 TQObject *obj;
61 while ( (obj = it.current()) != 0 ) {
62 ++it;
63 static_cast<TQPushButton*>(obj)->hide();
64 }
65 delete l;
66 }
67 {
68 TQObjectList *l = queryList("TQWidget");
69 TQObjectListIt it( *l );
70 TQObject *obj;
71 while ( (obj = it.current()) != 0 ) {
72 ++it;
73 static_cast<TQWidget*>(obj)->installEventFilter(this);
74 }
75 delete l;
76 }
77
78#ifdef TQ_WS_WIN
79 if (startDirOrVariable.startsWith(":"))
80 m_lastVisitedPathsVariable = startDirOrVariable; //store for later use
81#else
82 toggleSpeedbar(false);
83 setFocusProxy( locationEdit );//locationWidget() );
84#endif
85}
86
87KexiStartupFileDialog::~KexiStartupFileDialog()
88{
89#ifdef TQ_WS_WIN
90 saveLastVisitedPath(currentFileName());
91#endif
92}
93
94void KexiStartupFileDialog::setMode(int mode)
95{
96 //delayed
97 m_mode = mode;
98 m_filtersUpdated = false;
99}
100
101TQStringList KexiStartupFileDialog::additionalFilters() const
102{
103 return m_additionalMimeTypes;
104}
105
106void KexiStartupFileDialog::setAdditionalFilters(const TQStringList &mimeTypes)
107{
108 //delayed
109 m_additionalMimeTypes = mimeTypes;
110 m_filtersUpdated = false;
111}
112
113TQStringList KexiStartupFileDialog::excludedFilters() const
114{
115 return m_excludedMimeTypes;
116}
117
118void KexiStartupFileDialog::setExcludedFilters(const TQStringList &mimeTypes)
119{
120 //delayed
121 m_excludedMimeTypes = mimeTypes;
122 m_filtersUpdated = false;
123}
124
125void KexiStartupFileDialog::updateFilters()
126{
127 if (m_filtersUpdated)
128 return;
129 m_filtersUpdated = true;
130
131 m_lastFileName = TQString();
132// m_lastUrl = KURL();
133
134 clearFilter();
135
136 TQString filter;
137 KMimeType::Ptr mime;
138 TQStringList allfilters;
139
140 const bool normalOpeningMode = m_mode & Opening && !(m_mode & Custom);
141 const bool normalSavingMode = m_mode & SavingFileBasedDB && !(m_mode & Custom);
142
143 if (normalOpeningMode || normalSavingMode) {
144 mime = KMimeType::mimeType( KexiDB::Driver::defaultFileBasedDriverMimeType() );
145 if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
146 filter += KexiUtils::fileDialogFilterString(mime);
147 allfilters += mime->patterns();
148 }
149 }
150 if (normalOpeningMode || m_mode & SavingServerBasedDB) {
151 mime = KMimeType::mimeType("application/x-kexiproject-shortcut");
152 if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
153 filter += KexiUtils::fileDialogFilterString(mime);
154 allfilters += mime->patterns();
155 }
156 }
157 if (normalOpeningMode || m_mode & SavingServerBasedDB) {
158 mime = KMimeType::mimeType("application/x-kexi-connectiondata");
159 if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
160 filter += KexiUtils::fileDialogFilterString(mime);
161 allfilters += mime->patterns();
162 }
163 }
164
166 if (normalOpeningMode) {
167 mime = KMimeType::mimeType("application/x-msaccess");
168 if (mime && m_excludedMimeTypes.find(mime->name())==m_excludedMimeTypes.end()) {
169 filter += KexiUtils::fileDialogFilterString(mime);
170 allfilters += mime->patterns();
171 }
172 }
173
174 foreach (TQStringList::ConstIterator, it, m_additionalMimeTypes) {
175 if (*it == "all/allfiles")
176 continue;
177 if (m_excludedMimeTypes.find(*it)!=m_excludedMimeTypes.end())
178 continue;
180 mime = KMimeType::mimeType(*it);
181 allfilters += mime->patterns();
182 }
183
184 if (m_excludedMimeTypes.find("all/allfiles")==m_excludedMimeTypes.end())
185 filter += KexiUtils::fileDialogFilterString("all/allfiles");
186// mime = KMimeType::mimeType("all/allfiles");
187// if (mime) {
188// filter += TQString(mime->patterns().isEmpty() ? "*" : mime->patterns().join(" "))
189// + "|" + mime->comment()+ " (*)\n";
190// }
191 //remove duplicates made because upper- and lower-case extenstions are used:
192 TQStringList allfiltersUnique;
193 TQDict<char> uniqueDict(499, false);
194 foreach (TQStringList::ConstIterator, it, allfilters) {
195// kdDebug() << *it << endl;
196 uniqueDict.insert(*it, (char*)1);
197 }
198 foreach_dict (TQDictIterator<char>, it, uniqueDict) {
199 allfiltersUnique += it.currentKey();
200 }
201 allfiltersUnique.sort();
202
203 if (allfiltersUnique.count()>1) {//prepend "all supoported files" entry
204 filter.prepend(allfilters.join(" ")+"|" + i18n("All Supported Files")
205 +" ("+allfiltersUnique.join(" ")+")\n");
206 }
207
208 if (filter.right(1)=="\n")
209 filter.truncate(filter.length()-1);
210 setFilter(filter);
211
212 if (m_mode & Opening) {
213 KexiStartupFileDialogBase::setMode( KFile::ExistingOnly | KFile::LocalOnly | KFile::File );
214 setOperationMode( KFileDialog::Opening );
215 } else {
216 KexiStartupFileDialogBase::setMode( KFile::LocalOnly | KFile::File );
217 setOperationMode( KFileDialog::Saving );
218 }
219}
220
221void KexiStartupFileDialog::show()
222{
223 m_filtersUpdated = false;
224 updateFilters();
225 KexiStartupFileDialogBase::show();
226}
227
228//KURL KexiStartupFileDialog::currentURL()
229TQString KexiStartupFileDialog::currentFileName()
230{
231 setResult( TQDialog::Accepted ); // selectedURL tests for it
232
233#ifdef TQ_WS_WIN
234// TQString path = selectedFile();
235 //js @todo
236// kdDebug() << "selectedFile() == " << path << " '" << url().fileName() << "' " << m_lineEdit->text() << endl;
237 TQString path = dir()->absPath();
238 if (!path.endsWith("/") && !path.endsWith("\\"))
239 path.append("/");
240 path += m_lineEdit->text();
241// TQString path = TQFileInfo(selectedFile()).dirPath(true) + "/" + m_lineEdit->text();
242#else
243// TQString path = locationEdit->currentText().stripWhiteSpace(); //url.path().stripWhiteSpace(); that does not work, if the full path is not in the location edit !!!!!
244 TQString path=KexiStartupFileDialogBase::selectedURL().path();
245 kdDebug() << "prev selectedURL() == " << path <<endl;
246 kdDebug() << "locationEdit == " << locationEdit->currentText().stripWhiteSpace() <<endl;
247 //make sure user-entered path is acceped:
248 setSelection( locationEdit->currentText().stripWhiteSpace() );
249
250 path=KexiStartupFileDialogBase::selectedURL().path();
251 kdDebug() << "selectedURL() == " << path <<endl;
252
253#endif
254
255 if (!currentFilter().isEmpty()) {
256 if (m_mode & SavingFileBasedDB) {
257 TQStringList filters = TQStringList::split(" ", currentFilter()); //.first().stripWhiteSpace();
258 kdDebug()<< " filter == " << filters << endl;
259 TQString ext = TQFileInfo(path).extension(false);
260 bool hasExtension = false;
261 for (TQStringList::ConstIterator filterIt = filters.constBegin();
262 filterIt != filters.constEnd() && !hasExtension; ++filterIt)
263 {
264 TQString f( (*filterIt).stripWhiteSpace() );
265 hasExtension = !f.mid(2).isEmpty() && ext==f.mid(2);
266 }
267 if (!hasExtension) {
268 //no extension: add one
269 TQString defaultExtension( m_defaultExtension );
270 if (defaultExtension.isEmpty())
271 defaultExtension = filters.first().stripWhiteSpace().mid(2); //first one
272 path+=(TQString(".")+defaultExtension);
273 kdDebug() << "KexiStartupFileDialog::checkURL(): append extension, " << path << endl;
274 setSelection( path );
275 }
276 }
277 }
278 kdDebug() << "KexiStartupFileDialog::currentFileName() == " << path <<endl;
279 return path;
280// return KFileDialog::selectedURL();
281}
282
283//bool KexiStartupFileDialog::checkURL()
285{
286// KURL url = currentURL();
287// TQString path = url.path().stripWhiteSpace();
288 TQString path = currentFileName().stripWhiteSpace();
289
290// if (url.fileName().stripWhiteSpace().isEmpty()) {
291 if (path.isEmpty()) {
292 KMessageBox::error( this, i18n( "Enter a filename." ));
293 return false;
294 }
295
296 kdDebug() << "KexiStartupFileDialog::checkURL() path: " << path << endl;
297// kdDebug() << "KexiStartupFileDialog::checkURL() fname: " << url.fileName() << endl;
298//todo if ( url.isLocalFile() ) {
299 TQFileInfo fi(path);
300 if (mode() & KFile::ExistingOnly) {
301 if ( !fi.exists() ) {
302 KMessageBox::error( this, "<qt>"+i18n( "The file \"%1\" does not exist." )
303 .arg( TQDir::convertSeparators(path) ) );
304 return false;
305 }
306 else if (mode() & KFile::File) {
307 if (!fi.isFile()) {
308 KMessageBox::error( this, "<qt>"+i18n( "Enter a filename." ) );
309 return false;
310 }
311 else if (!fi.isReadable()) {
312 KMessageBox::error( this, "<qt>"+i18n( "The file \"%1\" is not readable." )
313 .arg( TQDir::convertSeparators(path) ) );
314 return false;
315 }
316 }
317 }
318 else if (m_confirmOverwrites && !askForOverwriting( path, this )) {
319 return false;
320 }
321// }
322 return true;
323}
324
325//static
326bool KexiStartupFileDialog::askForOverwriting(const TQString& filePath, TQWidget *parent)
327{
328 TQFileInfo fi(filePath);
329 if (!fi.exists())
330 return true;
331 const int res = KMessageBox::warningYesNo( parent, i18n( "The file \"%1\" already exists.\n"
332 "Do you want to overwrite it?").arg( TQDir::convertSeparators(filePath) ), TQString(),
333 i18n("Overwrite"), KStdGuiItem::no() );
334 if (res == KMessageBox::Yes)
335 return true;
336 return false;
337}
338
339void KexiStartupFileDialog::accept()
340{
341// locationEdit->setFocus();
342// TQKeyEvent ev(TQEvent::KeyPress, TQt::Key_Enter, '\n', 0);
343// TQApplication::sendEvent(locationEdit, &ev);
344// TQApplication::postEvent(locationEdit, &ev);
345
346// kdDebug() << "KexiStartupFileDialog::accept() m_lastUrl == " << m_lastUrl.path() << endl;
347// if (m_lastUrl.path()==currentURL().path()) {//(js) to prevent more multiple kjob signals (I do not know why this is)
348 if (m_lastFileName==currentFileName()) {//(js) to prevent more multiple kjob signals (I do not know why this is)
349// m_lastUrl=KURL();
350 m_lastFileName=TQString();
351 kdDebug() << "m_lastFileName==currentFileName()" << endl;
352#ifdef TQ_WS_WIN
353 return;
354#endif
355 }
356// kdDebug() << "KexiStartupFileDialog::accept(): url = " << currentURL().path() << " " << endl;
357 kdDebug() << "KexiStartupFileDialog::accept(): path = " << currentFileName() << endl;
358// if ( checkURL() ) {
359 if ( checkFileName() ) {
360 emit accepted();
361 }
362// else {
363// m_lastUrl = KURL();
364// }
365// m_lastUrl = currentURL();
366 m_lastFileName = currentFileName();
367
368#ifdef TQ_WS_WIN
369 saveLastVisitedPath(m_lastFileName);
370#endif
371}
372
373void KexiStartupFileDialog::reject()
374{
375 kdDebug() << "KexiStartupFileDialog: reject!" << endl;
376 emit rejected();
377}
378
379/*#ifndef TQ_WS_WIN
380KURLComboBox *KexiStartupFileDialog::locationWidget() const
381{
382 return locationEdit;
383}
384#endif
385*/
386
388{
389#ifdef TQ_WS_WIN
390 //js @todo
391 setSelection(fn);
392#else
393 setSelection(fn);
394// locationEdit->setCurrentText(fn);
395// locationEdit->lineEdit()->setEdited( true );
396// setSelection(fn);
397#endif
398}
399
400void KexiStartupFileDialog::setFocus()
401{
402#ifdef TQ_WS_WIN
403 m_lineEdit->setFocus();
404#else
405 locationEdit->setFocus();
406#endif
407}
408
409bool KexiStartupFileDialog::eventFilter ( TQObject * watched, TQEvent * e )
410{
411 //filter-out ESC key
412 if (e->type()==TQEvent::KeyPress && static_cast<TQKeyEvent*>(e)->key()==TQt::Key_Escape
413 && static_cast<TQKeyEvent*>(e)->state()==TQt::NoButton) {
414 static_cast<TQKeyEvent*>(e)->accept();
415 emit rejected();
416 return true;
417 }
418 return KexiStartupFileDialogBase::eventFilter(watched,e);
419}
420
421#include "KexiStartupFileDialog.moc"
422
static TQString defaultFileBasedDriverMimeType()
Definition driver.cpp:137
void setAdditionalFilters(const TQStringList &mimeTypes)
Sets additional filters list, e.g. "text/x-csv".
static bool askForOverwriting(const TQString &filePath, TQWidget *parent=0)
void setLocationText(const TQString &fn)
void setExcludedFilters(const TQStringList &mimeTypes)
Excludes filters list.
KEXIUTILS_EXPORT TQString fileDialogFilterString(const KMimeType::Ptr &mime, bool kdeFormat=true)