kexi

kexipartmanager.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
00003    Copyright (C) 2003-2005 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <klibloader.h>
00022 #include <ktrader.h>
00023 #include <kdebug.h>
00024 #include <kconfig.h>
00025 #include <kparts/componentfactory.h>
00026 
00027 #include "kexipartmanager.h"
00028 #include "kexipart.h"
00029 #include "kexipartinfo.h"
00030 #include "kexistaticpart.h"
00031 #include "kexi_version.h"
00032 
00033 #include <kexidb/connection.h>
00034 #include <kexidb/cursor.h>
00035 
00036 using namespace KexiPart;
00037 
00038 Manager::Manager(QObject *parent)
00039  : QObject(parent)
00040 {
00041     m_lookupDone = false;
00042     m_partlist.setAutoDelete(true);
00043     m_partsByMime.setAutoDelete(false);
00044     m_parts.setAutoDelete(false);//KApp will remove parts
00045     m_nextTempProjectPartID = -1;
00046 }
00047 
00048 void
00049 Manager::lookup()
00050 {
00051 //js: TODO: allow refreshing!!!! (will need calling removeClient() by Part objects)
00052     if (m_lookupDone)
00053         return;
00054     m_lookupDone = true;
00055     m_partlist.clear();
00056     m_partsByMime.clear();
00057     m_parts.clear();
00058     KTrader::OfferList tlist = KTrader::self()->query("Kexi/Handler", 
00059         "[X-Kexi-PartVersion] == " + QString::number(KEXI_PART_VERSION));
00060     
00061     KConfig conf("kexirc", true);
00062     conf.setGroup("Parts");
00063     QStringList sl_order = QStringList::split( ",", conf.readEntry("Order") );//we'll set parts in defined order
00064     const int size = QMAX( tlist.count(), sl_order.count() );
00065     QPtrVector<KService> ordered( size*2 );
00066     int offset = size; //we will insert not described parts from #offset
00067     
00068     //compute order
00069     for(KTrader::OfferList::ConstIterator it(tlist.constBegin()); it != tlist.constEnd(); ++it)
00070     {
00071         KService::Ptr ptr = (*it);
00072         QCString mime = ptr->property("X-Kexi-TypeMime").toCString();
00073         kdDebug() << "Manager::lookup(): " << mime << endl;
00074 //<TEMP>: disable some parts if needed
00075         if (!Kexi::tempShowForms() && mime=="kexi/form")
00076             continue;
00077         if (!Kexi::tempShowReports() && mime=="kexi/report")
00078             continue;
00079         if (!Kexi::tempShowMacros() && mime=="kexi/macro")
00080             continue;
00081         if (!Kexi::tempShowScripts() && mime=="kexi/script")
00082             continue;
00083 //</TEMP>
00084         int idx = sl_order.findIndex( ptr->library() );
00085         if (idx!=-1)
00086             ordered.insert(idx, ptr);
00087         else //add to end
00088             ordered.insert(offset++, ptr);  
00089     }
00090     //fill final list using computed order
00091     for (int i = 0; i< (int)ordered.size(); i++) {
00092         KService::Ptr ptr = ordered[i];
00093         if (ptr) {
00094             Info *info = new Info(ptr);
00095             info->setProjectPartID(m_nextTempProjectPartID--); // temp. part id are -1, -2, and so on, 
00096                                                                // to avoid duplicates
00097             if (!info->mimeType().isEmpty()) {
00098                 m_partsByMime.insert(info->mimeType(), info);
00099                 kdDebug() << "Manager::lookup(): inserting info to " << info->mimeType() << endl;
00100             }
00101             m_partlist.append(info);
00102         }
00103     }
00104 }
00105 
00106 Manager::~Manager()
00107 {
00108 }
00109 
00110 Part *
00111 Manager::part(Info *i)
00112 {
00113     clearError();
00114     if(!i)
00115         return 0;
00116 
00117 //  kdDebug() << "Manager::part( id = " << i->projectPartID() << " )" << endl;
00118 
00119     if (i->isBroken()) {
00120             setError(i->errorMessage());
00121             return 0;
00122     }
00123 
00124     Part *p = m_parts[i->projectPartID()];
00125     
00126     if(!p) {
00127 //      kdDebug() << "Manager::part().." << endl;
00128         int error=0;
00129         p = KParts::ComponentFactory::createInstanceFromService<Part>(i->ptr(), this, 
00130             QString(i->objectName()+"_part").latin1(), QStringList(), &error);
00131         if(!p) {
00132             kdDebug() << "Manager::part(): failed :( (ERROR #" << error << ")" << endl;
00133             kdDebug() << "  " << KLibLoader::self()->lastErrorMessage() << endl;
00134             i->setBroken(true, i18n("Error while loading plugin \"%1\"").arg(i->objectName()));
00135             setError(i->errorMessage());
00136             return 0;
00137         }
00138         if (p->m_registeredPartID>0) {
00139             i->setProjectPartID( p->m_registeredPartID );
00140         }
00141 
00142         p->setInfo(i);
00143         m_parts.insert(i->projectPartID(),p);
00144         emit partLoaded(p);
00145     }
00146     else {
00147 //      kdDebug() << "Manager::part(): cached: " << i->groupName() << endl;
00148     }
00149 
00150 //  kdDebug() << "Manager::part(): fine!" << endl;
00151     return p;
00152 }
00153 
00154 #if 0
00155 void
00156 Manager::unloadPart(Info *i)
00157 {
00158     m_parts.setAutoDelete(true);
00159     m_parts.remove(i->projectPartID());
00160     m_parts.setAutoDelete(false);
00161 /*  if (!p)
00162         return;
00163     m_partsByMime.take(i->mime());
00164     m_partlist.removeRef(p);*/
00165 }
00166 
00167 void 
00168 Manager::unloadAllParts()
00169 {
00170 //  m_partsByMime.clear();
00171     m_parts.setAutoDelete(true);
00172     m_parts.clear();
00173     m_parts.setAutoDelete(false);
00174 //  m_partlist.clear();
00175 }
00176 #endif
00177 
00178 /*void 
00179 Manager::removeClients( KexiMainWindow *win )
00180 {
00181     if (!win)
00182         return;
00183     QIntDictIterator<Part> it(m_parts);
00184     for (;i.current();++it) {
00185         i.current()->removeClient(win->guiFactory());
00186     }
00187 }*/
00188 
00189 Part *
00190 Manager::partForMimeType(const QString &mimeType)
00191 {
00192     return mimeType.isEmpty() ? 0 : part(m_partsByMime[mimeType.latin1()]);
00193 }
00194 
00195 Info *
00196 Manager::infoForMimeType(const QString &mimeType)
00197 {
00198     Info *i = mimeType.isEmpty() ? 0 : m_partsByMime[mimeType.latin1()];
00199     if (i)
00200         return i;
00201     setError(i18n("No plugin for mime type \"%1\"").arg(mimeType));
00202     return 0;
00203 }
00204 
00205 
00206 bool
00207 Manager::checkProject(KexiDB::Connection *conn)
00208 {
00209     clearError();
00210 //  QString errmsg = i18n("Invalid project contents.");
00211 
00212 //TODO: catch errors!
00213     if(!conn->isDatabaseUsed()) {
00214         setError(conn);
00215         return false;
00216     }
00217 
00218     KexiDB::Cursor *cursor = conn->executeQuery("SELECT * FROM kexi__parts");//, KexiDB::Cursor::Buffered);
00219     if(!cursor) {
00220         setError(conn);
00221         return false;
00222     }
00223 
00224 //  int id=0;
00225 //  QStringList parts_found;
00226     for(cursor->moveFirst(); !cursor->eof(); cursor->moveNext())
00227     {
00228 //      id++;
00229         Info *i = infoForMimeType(cursor->value(2).toCString());
00230         if(!i)
00231         {
00232             Missing m;
00233             m.name = cursor->value(1).toString();
00234             m.mime = cursor->value(2).toCString();
00235             m.url = cursor->value(3).toString();
00236 
00237             m_missing.append(m);
00238         }
00239         else
00240         {
00241             i->setProjectPartID(cursor->value(0).toInt());
00242             i->setIdStoredInPartDatabase(true);
00243 //          parts_found+=cursor->value(2).toString();
00244         }
00245     }
00246 
00247     conn->deleteCursor(cursor);
00248 
00249 #if 0 //js: moved to Connection::createDatabase()
00250     //add missing default part entries
00251     KexiDB::TableSchema *ts = conn->tableSchema("kexi__parts");
00252     if (!ts)
00253         return false;
00254     KexiDB::FieldList *fl = ts->subList("p_id", "p_name", "p_mime", "p_url");
00255     if (!fl)
00256         return false;
00257     if (!parts_found.contains("kexi/table")) {
00258         if (!conn->insertRecord(*fl, QVariant(1), QVariant("Tables"), QVariant("kexi/table"), QVariant("http://")))
00259             return false;
00260     }
00261     if (!parts_found.contains("kexi/query")) {
00262         if (!conn->insertRecord(*fl, QVariant(2), QVariant("Queries"), QVariant("kexi/query"), QVariant("http://")))
00263             return false;
00264     }
00265 #endif
00266     return true;
00267 }
00268 
00269 void Manager::insertStaticPart(StaticPart* part)
00270 {
00271     if (!part)
00272         return;
00273     part->info()->setProjectPartID(m_nextTempProjectPartID--); // temp. part id are -1, -2, and so on, 
00274     m_partlist.append(part->info());
00275     if (!part->info()->mimeType().isEmpty())
00276         m_partsByMime.insert(part->info()->mimeType(), part->info());
00277     m_parts.insert(part->info()->projectPartID(), part);
00278 }
00279 
00280 #include "kexipartmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys