kexi

kexicsvexportwizard.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005,2006 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 "kexicsvexportwizard.h"
21#include "kexicsvwidgets.h"
22#include <main/startup/KexiStartupFileDialog.h>
23#include <kexidb/cursor.h>
24#include <kexidb/utils.h>
25#include <core/keximainwindow.h>
26#include <core/kexiproject.h>
27#include <core/kexipartinfo.h>
28#include <core/kexipartmanager.h>
29#include <core/kexiguimsghandler.h>
30#include <kexiutils/utils.h>
31#include <widget/kexicharencodingcombobox.h>
32
33#include <tqcheckbox.h>
34#include <tqgroupbox.h>
35#include <tqclipboard.h>
36#include <tdeapplication.h>
37#include <tdelocale.h>
38#include <kiconloader.h>
39#include <kactivelabel.h>
40#include <kpushbutton.h>
41#include <tdeapplication.h>
42#include <kdebug.h>
43#include <ksavefile.h>
44
45
47 KexiMainWindow* mainWin, TQWidget * parent, const char * name )
48 : KWizard(parent, name)
49 , m_options(options)
50// , m_mode(mode)
51// , m_itemId(itemId)
52 , m_mainWin(mainWin)
53 , m_fileSavePage(0)
54 , m_defaultsBtn(0)
55 , m_rowCount(-1)
56 , m_rowCountDetermined(false)
57 , m_cancelled(false)
58{
59 if (m_options.mode==KexiCSVExport::Clipboard) {
60 finishButton()->setText(i18n("Copy"));
61 backButton()->hide();
62 }
63 else {
64 finishButton()->setText(i18n("Export"));
65 }
66 helpButton()->hide();
67
68 TQString infoLblFromText;
69 KexiGUIMessageHandler msgh(this);
70 m_tableOrQuery = new KexiDB::TableOrQuerySchema(
71 m_mainWin->project()->dbConnection(), m_options.itemId);
72 if (m_tableOrQuery->table()) {
73 if (m_options.mode==KexiCSVExport::Clipboard) {
74 setCaption(i18n("Copy Data From Table to Clipboard"));
75 infoLblFromText = i18n("Copying data from table:");
76 }
77 else {
78 setCaption(i18n("Export Data From Table to CSV File"));
79 infoLblFromText = i18n("Exporting data from table:");
80 }
81 }
82 else if (m_tableOrQuery->query()) {
83 if (m_options.mode==KexiCSVExport::Clipboard) {
84 setCaption(i18n("Copy Data From Query to Clipboard"));
85 infoLblFromText = i18n("Copying data from table:");
86 }
87 else {
88 setCaption(i18n("Export Data From Query to CSV File"));
89 infoLblFromText = i18n("Exporting data from query:");
90 }
91 }
92 else {
93 msgh.showErrorMessage(m_mainWin->project()->dbConnection(),
94 i18n("Could not open data for exporting."));
95 m_cancelled = true;
96 return;
97 }
98 // OK, source data found.
99
100 // Setup pages
101
102 // 1. File Save Page
103 if (m_options.mode==KexiCSVExport::File) {
104 m_fileSavePage = new KexiStartupFileDialog(
105 ":CSVImportExport", //startDir
106 KexiStartupFileDialog::Custom | KexiStartupFileDialog::SavingFileBasedDB,
107 this, "m_fileSavePage");
108 m_fileSavePage->setMinimumHeight(kapp->desktop()->height()/2);
109 m_fileSavePage->setAdditionalFilters( csvMimeTypes() );
110 m_fileSavePage->setDefaultExtension("csv");
111 m_fileSavePage->setLocationText( KexiUtils::stringToFileName(m_tableOrQuery->captionOrName()) );
112 connect(m_fileSavePage, TQ_SIGNAL(rejected()), this, TQ_SLOT(reject()));
113 addPage(m_fileSavePage, i18n("Enter Name of File You Want to Save Data To"));
114 }
115
116 // 2. Export options
117 m_exportOptionsPage = new TQWidget(this, "m_exportOptionsPage");
118 TQGridLayout *exportOptionsLyr = new TQGridLayout( m_exportOptionsPage, 6, 3,
119 KDialogBase::marginHint(), KDialogBase::spacingHint(), "exportOptionsLyr");
120 m_infoLblFrom = new KexiCSVInfoLabel( infoLblFromText, m_exportOptionsPage );
122 m_tableOrQuery->table() ? "kexi/table" : "kexi/query");
123 if (partInfo)
124 m_infoLblFrom->setIcon(partInfo->itemIcon());
125 m_infoLblFrom->separator()->hide();
126 exportOptionsLyr->addMultiCellWidget(m_infoLblFrom, 0, 0, 0, 2);
127
128 m_infoLblTo = new KexiCSVInfoLabel(
129 (m_options.mode==KexiCSVExport::File) ? i18n("To CSV file:") : i18n("To clipboard:"),
130 m_exportOptionsPage
131 );
132 if (m_options.mode==KexiCSVExport::Clipboard)
133 m_infoLblTo->setIcon("edit-paste");
134 exportOptionsLyr->addMultiCellWidget(m_infoLblTo, 1, 1, 0, 2);
135
136 m_showOptionsButton = new KPushButton(KGuiItem(i18n("Show Options >>"), "configure"),
137 m_exportOptionsPage);
138 connect(m_showOptionsButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotShowOptionsButtonClicked()));
139 exportOptionsLyr->addMultiCellWidget(m_showOptionsButton, 2, 2, 0, 0);
140 m_showOptionsButton->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed);
141
142 // -<options section>
143 m_exportOptionsSection = new TQGroupBox(1,TQt::Vertical, i18n("Options"), m_exportOptionsPage,
144 "m_exportOptionsSection");
145 m_exportOptionsSection->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed);
146 exportOptionsLyr->addMultiCellWidget(m_exportOptionsSection, 3, 3, 0, 1);
147 TQWidget *exportOptionsSectionWidget
148 = new TQWidget(m_exportOptionsSection, "exportOptionsSectionWidget");
149 TQGridLayout *exportOptionsSectionLyr = new TQGridLayout( exportOptionsSectionWidget, 5, 2,
150 0, KDialogBase::spacingHint(), "exportOptionsLyr");
151
152 // -delimiter
153 m_delimiterWidget = new KexiCSVDelimiterWidget(false,
154 exportOptionsSectionWidget);
155 m_delimiterWidget->setDelimiter(defaultDelimiter());
156 exportOptionsSectionLyr->addWidget( m_delimiterWidget, 0, 1 );
157 TQLabel *delimiterLabel = new TQLabel(m_delimiterWidget, i18n("Delimiter:"), exportOptionsSectionWidget);
158 exportOptionsSectionLyr->addWidget( delimiterLabel, 0, 0 );
159
160 // -text quote
161 TQWidget *textQuoteWidget = new TQWidget(exportOptionsSectionWidget);
162 TQHBoxLayout *textQuoteLyr = new TQHBoxLayout(textQuoteWidget);
163 exportOptionsSectionLyr->addWidget(textQuoteWidget, 1, 1);
164 m_textQuote = new KexiCSVTextQuoteComboBox( textQuoteWidget );
165 m_textQuote->setTextQuote(defaultTextQuote());
166 textQuoteLyr->addWidget( m_textQuote );
167 textQuoteLyr->addStretch(0);
168 TQLabel *textQuoteLabel = new TQLabel(m_textQuote, i18n("Text quote:"), exportOptionsSectionWidget);
169 exportOptionsSectionLyr->addWidget( textQuoteLabel, 1, 0 );
170
171 // - character encoding
172 m_characterEncodingCombo = new KexiCharacterEncodingComboBox( exportOptionsSectionWidget );
173 m_characterEncodingCombo->setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed);
174 exportOptionsSectionLyr->addWidget( m_characterEncodingCombo, 2, 1 );
175 TQLabel *characterEncodingLabel = new TQLabel(m_characterEncodingCombo, i18n("Text encoding:"),
176 exportOptionsSectionWidget);
177 exportOptionsSectionLyr->addWidget( characterEncodingLabel, 2, 0 );
178
179 // - checkboxes
180 m_addColumnNamesCheckBox = new TQCheckBox(i18n("Add column names as the first row"),
181 exportOptionsSectionWidget);
182 m_addColumnNamesCheckBox->setChecked(true);
183 exportOptionsSectionLyr->addWidget( m_addColumnNamesCheckBox, 3, 1 );
185 m_alwaysUseCheckBox = new TQCheckBox(i18n("Always use above options for exporting"),
186 m_exportOptionsPage);
187 exportOptionsLyr->addMultiCellWidget(m_alwaysUseCheckBox, 4, 4, 0, 1);
188// exportOptionsSectionLyr->addWidget( m_alwaysUseCheckBox, 4, 1 );
189 m_exportOptionsSection->hide();
190 m_alwaysUseCheckBox->hide();
191 // -</options section>
192
193// exportOptionsLyr->setColStretch(3, 1);
194 exportOptionsLyr->addMultiCell(
195 new TQSpacerItem( 0, 0, TQSizePolicy::Preferred, TQSizePolicy::MinimumExpanding), 5, 5, 0, 1 );
196
197// addPage(m_exportOptionsPage, i18n("Set Export Options"));
198 addPage(m_exportOptionsPage, m_options.mode==KexiCSVExport::Clipboard ? i18n("Copying") : i18n("Exporting"));
199 setFinishEnabled(m_exportOptionsPage, true);
200
201 // load settings
202 kapp->config()->setGroup("ImportExport");
203 if (m_options.mode!=KexiCSVExport::Clipboard && readBoolEntry("ShowOptionsInCSVExportDialog", false)) {
204 show();
205 slotShowOptionsButtonClicked();
206 }
207 if (readBoolEntry("StoreOptionsForCSVExportDialog", false)) {
208 // load defaults:
209 m_alwaysUseCheckBox->setChecked(true);
210 TQString s = readEntry("DefaultDelimiterForExportingCSVFiles", defaultDelimiter());
211 if (!s.isEmpty())
212 m_delimiterWidget->setDelimiter(s);
213 s = readEntry("DefaultTextQuoteForExportingCSVFiles", defaultTextQuote());
214 m_textQuote->setTextQuote(s); //will be invaliudated here, so not a problem
215 s = readEntry("DefaultEncodingForExportingCSVFiles");
216 if (!s.isEmpty())
217 m_characterEncodingCombo->setSelectedEncoding(s);
218 m_addColumnNamesCheckBox->setChecked(
219 readBoolEntry("AddColumnNamesForExportingCSVFiles", true) );
220 }
221
222 updateGeometry();
223
224 // -keep widths equal on page #2:
225 int width = TQMAX( m_infoLblFrom->leftLabel()->sizeHint().width(),
226 m_infoLblTo->leftLabel()->sizeHint().width());
227 m_infoLblFrom->leftLabel()->setFixedWidth(width);
228 m_infoLblTo->leftLabel()->setFixedWidth(width);
229}
230
231KexiCSVExportWizard::~KexiCSVExportWizard()
232{
233 delete m_tableOrQuery;
234}
235
236bool KexiCSVExportWizard::cancelled() const
237{
238 return m_cancelled;
239}
240
241void KexiCSVExportWizard::showPage ( TQWidget * page )
242{
243 if (page == m_fileSavePage) {
244 m_fileSavePage->setFocus();
245 }
246 else if (page==m_exportOptionsPage) {
247 if (m_options.mode==KexiCSVExport::File)
248 m_infoLblTo->setFileName( m_fileSavePage->currentFileName() );
249 TQString text = m_tableOrQuery->captionOrName();
250 if (!m_rowCountDetermined) {
251 //do this costly operation only once
252 m_rowCount = KexiDB::rowCount(*m_tableOrQuery);
253 m_rowCountDetermined = true;
254 }
255 int columns = KexiDB::fieldCount(*m_tableOrQuery);
256 text += "\n";
257 if (m_rowCount>0)
258 text += i18n("(rows: %1, columns: %2)").arg(m_rowCount).arg(columns);
259 else
260 text += i18n("(columns: %1)").arg(columns);
261 m_infoLblFrom->setLabelText(text);
262 TQFontMetrics fm(m_infoLblFrom->fileNameLabel()->font());
263 m_infoLblFrom->fileNameLabel()->setFixedHeight( fm.height() * 2 + fm.lineSpacing() );
264 if (m_defaultsBtn)
265 m_defaultsBtn->show();
266 }
267
268 if (page!=m_exportOptionsPage) {
269 if (m_defaultsBtn)
270 m_defaultsBtn->hide();
271 }
272
273 KWizard::showPage(page);
274}
275
276void KexiCSVExportWizard::next()
277{
278 if (currentPage() == m_fileSavePage) {
279 if (!m_fileSavePage->checkFileName())
280 return;
281 KWizard::next();
282 finishButton()->setFocus();
283 return;
284 }
285 KWizard::next();
286}
287
288void KexiCSVExportWizard::done(int result)
289{
290 if (TQDialog::Accepted == result) {
291 if (m_fileSavePage)
292 m_options.fileName = m_fileSavePage->currentFileName();
293 m_options.delimiter = m_delimiterWidget->delimiter();
294 m_options.textQuote = m_textQuote->textQuote();
295 m_options.addColumnNames = m_addColumnNamesCheckBox->isChecked();
296 if (!KexiCSVExport::exportData(*m_tableOrQuery, m_options))
297 return;
298 }
299 else if (TQDialog::Rejected == result) {
300 //nothing to do
301 }
302
303 //store options
304 kapp->config()->setGroup("ImportExport");
305 if (m_options.mode!=KexiCSVExport::Clipboard)
306 writeEntry("ShowOptionsInCSVExportDialog", m_exportOptionsSection->isVisible());
307 const bool store = m_alwaysUseCheckBox->isChecked();
308 writeEntry("StoreOptionsForCSVExportDialog", store);
309 // only save if an option differs from default
310
311 if (store && m_delimiterWidget->delimiter()!=defaultDelimiter())
312 writeEntry("DefaultDelimiterForExportingCSVFiles", m_delimiterWidget->delimiter());
313 else
314 deleteEntry("DefaultDelimiterForExportingCSVFiles");
315 if (store && m_textQuote->textQuote()!=defaultTextQuote())
316 writeEntry("DefaultTextQuoteForExportingCSVFiles", m_textQuote->textQuote());
317 else
318 deleteEntry("DefaultTextQuoteForExportingCSVFiles");
319 if (store && !m_characterEncodingCombo->defaultEncodingSelected())
320 writeEntry("DefaultEncodingForExportingCSVFiles", m_characterEncodingCombo->selectedEncoding());
321 else
322 deleteEntry("DefaultEncodingForExportingCSVFiles");
323 if (store && !m_addColumnNamesCheckBox->isChecked())
324 writeEntry("AddColumnNamesForExportingCSVFiles", m_addColumnNamesCheckBox->isChecked());
325 else
326 deleteEntry("AddColumnNamesForExportingCSVFiles");
327
328 KWizard::done(result);
329}
330
331void KexiCSVExportWizard::slotShowOptionsButtonClicked()
332{
333 if (m_exportOptionsSection->isVisible()) {
334 m_showOptionsButton->setText(i18n("Show Options >>"));
335 m_exportOptionsSection->hide();
336 m_alwaysUseCheckBox->hide();
337 if (m_defaultsBtn)
338 m_defaultsBtn->hide();
339 }
340 else {
341 m_showOptionsButton->setText(i18n("Hide Options <<"));
342 m_exportOptionsSection->show();
343 m_alwaysUseCheckBox->show();
344 if (m_defaultsBtn)
345 m_defaultsBtn->show();
346 }
347}
348
349void KexiCSVExportWizard::layOutButtonRow( TQHBoxLayout * layout )
350{
351 TQWizard::layOutButtonRow( layout );
352
353 //find the last sublayout
354 TQLayout *l = 0;
355 for (TQLayoutIterator lit( layout->iterator() ); lit.current(); ++lit)
356 l = lit.current()->layout();
357 if (dynamic_cast<TQBoxLayout*>(l)) {
358 if (!m_defaultsBtn) {
359 m_defaultsBtn = new KPushButton(i18n("Defaults"), this);
360 TQWidget::setTabOrder(backButton(), m_defaultsBtn);
361 connect(m_defaultsBtn, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDefaultsButtonClicked()));
362 }
363 if (!m_exportOptionsSection->isVisible())
364 m_defaultsBtn->hide();
365 dynamic_cast<TQBoxLayout*>(l)->insertWidget(0, m_defaultsBtn);
366 }
367}
368
369void KexiCSVExportWizard::slotDefaultsButtonClicked()
370{
371 m_delimiterWidget->setDelimiter(defaultDelimiter());
372 m_textQuote->setTextQuote(defaultTextQuote());
373 m_addColumnNamesCheckBox->setChecked(true);
374 m_characterEncodingCombo->selectDefaultEncoding();
375}
376
377static TQString convertKey(const char *key, KexiCSVExport::Mode mode)
378{
379 TQString _key(TQString::fromLatin1(key));
380 if (mode == KexiCSVExport::Clipboard) {
381 _key.replace("Exporting", "Copying");
382 _key.replace("Export", "Copy");
383 _key.replace("CSVFiles", "CSVToClipboard");
384 }
385 return _key;
386}
387
388bool KexiCSVExportWizard::readBoolEntry(const char *key, bool defaultValue)
389{
390 return kapp->config()->readBoolEntry(convertKey(key, m_options.mode), defaultValue);
391}
392
393TQString KexiCSVExportWizard::readEntry(const char *key, const TQString& defaultValue)
394{
395 return kapp->config()->readEntry(convertKey(key, m_options.mode), defaultValue);
396}
397
398void KexiCSVExportWizard::writeEntry(const char *key, const TQString& value)
399{
400 kapp->config()->writeEntry(convertKey(key, m_options.mode), value);
401}
402
403void KexiCSVExportWizard::writeEntry(const char *key, bool value)
404{
405 kapp->config()->writeEntry(convertKey(key, m_options.mode), value);
406}
407
409{
410 kapp->config()->deleteEntry(convertKey(key, m_options.mode));
411}
412
414{
415 if (m_options.mode==KexiCSVExport::Clipboard) {
416 if (!m_options.forceDelimiter.isEmpty())
417 return m_options.forceDelimiter;
418 else
419 return KEXICSV_DEFAULT_CLIPBOARD_DELIMITER;
420 }
421 return KEXICSV_DEFAULT_FILE_DELIMITER;
422}
423
425{
426 if (m_options.mode==KexiCSVExport::Clipboard)
427 return KEXICSV_DEFAULT_CLIPBOARD_TEXT_QUOTE;
428 return KEXICSV_DEFAULT_FILE_TEXT_QUOTE;
429}
430
431#include "kexicsvexportwizard.moc"
A combo box widget providing a list of possible delimiters Used by CSV import and export dialogs.
KexiCSVExportWizard(const KexiCSVExport::Options &options, KexiMainWindow *mainWin, TQWidget *parent=0, const char *name=0)
TQString readEntry(const char *key, const TQString &defaultValue=TQString())
Helper like readBoolEntry(const char *, bool), but for TQString values.
void deleteEntry(const char *key)
Helper like writeEntry(const char *, bool), but for deleting config entry.
virtual void layOutButtonRow(TQHBoxLayout *layout)
reimplemented to add "Defaults" button on the left hand
int m_rowCount
Cached row count for a table/query.
TQString defaultDelimiter() const
void writeEntry(const char *key, bool value)
bool readBoolEntry(const char *key, bool defaultValue)
TQString defaultTextQuote() const
Options used in KexiCSVExportWizard contructor.
A helper widget showing a short text information with an icon. See ctor for details....
A combo box widget providing a list of possible quote characters Used by CSV import and export dialog...
void setTextQuote(const TQString &textQuote)
Sets text quote. Only available are: ", ', and empty string.
Combobox widget providing a list of possible character encodings.
void selectDefaultEncoding()
Selects default encoding, if present.
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
Information about a Kexi Part (plugin).
TQString itemIcon() const
Info * infoForMimeType(const TQString &mimeType)
Widget for opening/saving files supported by Kexi.
int rowCount(Connection &conn, const TQString &sql)
KEXI_DB_EXPORT int fieldCount(TableOrQuerySchema &tableOrQuery)
KEXIUTILS_EXPORT TQString stringToFileName(const TQString &string)
KEXICORE_EXPORT KexiPart::Manager & partManager()
shared part manager
Definition kexi.cpp:97