kspread_kexiimport.cpp
1/***************************************************************************
2 * Copyright (C) 2006 by Adam Pigg *
3 * adam@piggz.co.uk *
4 * *
5 * Based on insert calendar code: *
6 * Copyright (C) 2005 by Raphael Langerhorst *
7 * raphael-langerhorst@gmx.at *
8 * *
9 * Permission is hereby granted, free of charge, to any person obtaining *
10 * a copy of this software and associated documentation files (the *
11 * "Software"), to deal in the Software without restriction, including *
12 * without limitation the rights to use, copy, modify, merge, publish, *
13 * distribute, sublicense, and/or sell copies of the Software, and to *
14 * permit persons to whom the Software is furnished to do so, subject to *
15 * the following conditions: *
16 * *
17 * The above copyright notice and this permission notice shall be *
18 * included in all copies or substantial portions of the Software. *
19 * *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
23 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 ***************************************************************************/
28
29#include "kspread_kexiimport.h"
30
31#include "kspread_kexiimportdialog.h"
32
33//KSpread Includes
34#include <kspread_view.h>
35#include <kspread_doc.h>
36//#include <selection.h>
37#include <kspread_sheet.h>
38#include <kspread_map.h>
39#include <kspread_style.h>
40
41//Koffice Includes
42#include <KoFilterChain.h>
43#include <KoFilterManager.h>
44#include <kofficeversion.h>
45
46//Kexi Includes
47#include <kexidb/cursor.h>
48#include <kexidb/connection.h>
49#include <kexidb/parser/parser.h>
50
51//KDE Includes
52#include <kgenericfactory.h>
53#include <tdelocale.h>
54#include <tdemessagebox.h>
55#include <tdelistview.h>
56#include <tqcolor.h>
57
58typedef KGenericFactory<KSpreadKexiImport, KoFilter> KSpreadKexiImportFactory;
59K_EXPORT_COMPONENT_FACTORY( libkspreadkexiimport, KSpreadKexiImportFactory( "kofficefilters" ) )
60
61
62//=============================================================================
63
64KSpreadKexiImport::KSpreadKexiImport(KoFilter *parent, const char *name, const TQStringList&)
65{
66}
67
68//=============================================================================
69
70KSpreadKexiImport::~KSpreadKexiImport()
71{
72 delete m_dialog;
73}
74
75//=============================================================================
76
77KoFilter::ConversionStatus KSpreadKexiImport::convert( const TQCString& from, const TQCString& to )
78{
79 TQPtrList<TQListViewItem> objects;
80 TQString file( m_chain->inputFile() );
81
82 //Create dialog
83 m_dialog = new KSpreadKexiImportDialog();
84
85 m_dialog->openDatabase( file, 0);
86 if (!m_dialog->exec())
87 {
88 return KoFilter::UserCancelled;
89 }
90
91 objects = m_dialog->selectedItems();
92
93 kdDebug() << "Getting Documents..." << endl;
94
95 KoDocument* document = m_chain->outputDocument();
96
97 if ( !document )
98 return KoFilter::StupidError;
99
100 kdDebug() << "here we go... " << document->className() << endl;
101
102 if ( !::tqt_cast<const KSpread::Doc *>( document ) )
103 {
104 kdWarning() << "document isn't a KSpread::Doc but a " << document->className() << endl;
105 return KoFilter::NotImplemented;
106 }
107 if(from!="application/x-kexiproject-sqlite3" || to!="application/x-kspread")
108 {
109 kdWarning() << "Invalid mimetypes " << from << " " << to << endl;
110 return KoFilter::NotImplemented;
111 }
112
113 ksdoc = static_cast<KSpread::Doc *>( document ); // type checked above
114
115 if(ksdoc->mimeType()!="application/x-kspread")
116 {
117 kdWarning() << "Invalid document mimetype " << ksdoc->mimeType() << endl;
118 return KoFilter::NotImplemented;
119 }
120
121 document->emitBeginOperation();
122
123 TQListViewItem *itm;
124 for(itm = objects.first(); itm ; itm = objects.next())
125 {
126 if (!insertObject(itm->text(1), itm->text(0)))
127 {
128 return KoFilter::StupidError;
129 }
130 }
131 if (m_dialog->customQuery())
132 {
133 if (!insertObject(m_dialog->customQueryString(), "Custom"))
134 {
135 return KoFilter::StupidError;
136 }
137 }
138
139 document->emitEndOperation();
140 kdDebug() << "inserting kexi data completed" << endl;
141 return KoFilter::OK;
142}
143
144bool KSpreadKexiImport::insertObject(const TQString& object, const TQString& type)
145{
146 TQStringList fieldNames;
147 KSpread::Sheet *sheet;
148 KexiDB::Parser *parser;
149 KexiDB::QuerySchema *query;
150
151 sheet = ksdoc->map()->addNewSheet();
152 if (!sheet)
153 {
154 KMessageBox::error(NULL, i18n("Cant find sheet"), i18n("Error"));
155 return false;
156 }
157
158 if (type == "Custom")
159 {
160 sheet->setSheetName("Custom");
161 }
162 else
163 {
164 sheet->setSheetName(object);
165 }
166
167 //Get the field names
168 if (type == "Table")
169 {
170 fieldNames = m_dialog->connection()->tableSchema(object)->names();
171 }
172 else if (type == "Query")
173 {
174 //Note....for queries such as select * from....field names are not available
175 fieldNames = m_dialog->connection()->querySchema(object)->names();
176 }
177 else if (type == "Custom") //Custom Query
178 {
179 parser = new KexiDB::Parser(m_dialog->connection());
180 parser->parse( object );
181
182 if (parser->operation() != KexiDB::Parser::OP_Select)
183 {
184 KMessageBox::error(NULL, i18n("Your query was invalid or not a SELECT query"), i18n("Error"));
185 return false;
186 }
187 query = parser->query();
188 fieldNames = query->names();
189 }
190
191 //Insert the field headings
192 TQStringList::iterator it;
193 int i = 1;
194 for (it = fieldNames.begin(); it != fieldNames.end(); ++it, ++i)
195 {
196 KSpread::Cell *c = sheet->nonDefaultCell(i ,1);
197 c->setCellText(*it, true);
198 c->format()->setBgColor(TQColor(200,200,200));
199 c->format()->setTextFontBold(true);
200 }
201
202 //Insert the data
203 KexiDB::Cursor *cur;
204 if (type == "Table") //Table
205 {
206 cur = m_dialog->connection()->executeQuery( *(m_dialog->connection()->tableSchema(object)));
207 }
208 else if (type == "Query") //Query
209 {
210 cur = m_dialog->connection()->executeQuery( *(m_dialog->connection()->querySchema(object)));
211 }
212 else if (type == "Custom") //Custom Query
213 {
214 cur = m_dialog->connection()->executeQuery( *query );
215 }
216 else
217 {
218 cur = 0;
219 }
220
221 if (!cur)
222 {
223 KMessageBox::error(NULL, i18n("Error executing query"), i18n("Error"));
224 return false;
225 }
226
227 cur->moveFirst();
228 int j = cur->fieldCount();
229
230 unsigned int k = 2; //start on row 2
231 bool asText = false;
232
233 if(m_dialog->conversion() == 2)
234 asText = true;
235
236 while (!cur->eof())
237 {
238 for (i = 0; i < j; ++i)
239 {
240 sheet->nonDefaultCell(i+1 ,k)->setCellText(cur->value(i).toString(), asText);
241 }
242
243 kdDebug() << k << endl;
244 cur->moveNext();
245 ++k;
246 }
247 return true;
248}
249#include "kspread_kexiimport.moc"