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::tempShowScripts() && mime=="kexi/script")
00080             continue;
00081 //</TEMP>
00082         int idx = sl_order.findIndex( ptr->library() );
00083         if (idx!=-1)
00084             ordered.insert(idx, ptr);
00085         else //add to end
00086             ordered.insert(offset++, ptr);  
00087     }
00088     //fill final list using computed order
00089     for (int i = 0; i< (int)ordered.size(); i++) {
00090         KService::Ptr ptr = ordered[i];
00091         if (ptr) {
00092             Info *info = new Info(ptr);
00093             info->setProjectPartID(m_nextTempProjectPartID--); // temp. part id are -1, -2, and so on, 
00094                                                                // to avoid duplicates
00095             if (!info->mimeType().isEmpty()) {
00096                 m_partsByMime.insert(info->mimeType(), info);
00097                 kdDebug() << "Manager::lookup(): inserting info to " << info->mimeType() << endl;
00098             }
00099             m_partlist.append(info);
00100         }
00101     }
00102 }
00103 
00104 Manager::~Manager()
00105 {
00106 }
00107 
00108 Part *
00109 Manager::part(Info *i)
00110 {
00111     clearError();
00112     if(!i)
00113         return 0;
00114 
00115     kdDebug() << "Manager::part( id = " << i->projectPartID() << " )" << endl;
00116 
00117     if (i->isBroken()) {
00118             setError(i->errorMessage());
00119             return 0;
00120     }
00121 
00122     Part *p = m_parts[i->projectPartID()];
00123     
00124     if(!p) {
00125         kdDebug() << "Manager::part().." << endl;
00126         int error=0;
00127         p = KParts::ComponentFactory::createInstanceFromService<Part>(i->ptr(), this, 
00128             QString(i->objectName()+"_part").latin1(), QStringList(), &error);
00129         if(!p) {
00130             kdDebug() << "Manager::part(): failed :( (ERROR #" << error << ")" << endl;
00131             kdDebug() << "  " << KLibLoader::self()->lastErrorMessage() << endl;
00132             i->setBroken(true, i18n("Error while loading plugin \"%1\"").arg(i->objectName()));
00133             setError(i->errorMessage());
00134             return 0;
00135         }
00136         if (p->m_registeredPartID>0) {
00137             i->setProjectPartID( p->m_registeredPartID );
00138         }
00139 
00140         p->setInfo(i);
00141         m_parts.insert(i->projectPartID(),p);
00142         emit partLoaded(p);
00143     }
00144     else {
00145         kdDebug() << "Manager::part(): cached: " << i->groupName() << endl;
00146     }
00147 
00148     kdDebug() << "Manager::part(): fine!" << endl;
00149     return p;
00150 }
00151 
00152 #if 0
00153 void
00154 Manager::unloadPart(Info *i)
00155 {
00156     m_parts.setAutoDelete(true);
00157     m_parts.remove(i->projectPartID());
00158     m_parts.setAutoDelete(false);
00159 /*  if (!p)
00160         return;
00161     m_partsByMime.take(i->mime());
00162     m_partlist.removeRef(p);*/
00163 }
00164 
00165 void 
00166 Manager::unloadAllParts()
00167 {
00168 //  m_partsByMime.clear();
00169     m_parts.setAutoDelete(true);
00170     m_parts.clear();
00171     m_parts.setAutoDelete(false);
00172 //  m_partlist.clear();
00173 }
00174 #endif
00175 
00176 /*void 
00177 Manager::removeClients( KexiMainWindow *win )
00178 {
00179     if (!win)
00180         return;
00181     QIntDictIterator<Part> it(m_parts);
00182     for (;i.current();++it) {
00183         i.current()->removeClient(win->guiFactory());
00184     }
00185 }*/
00186 
00187 Part *
00188 Manager::partForMimeType(const QString &mimeType)
00189 {
00190     return mimeType.isEmpty() ? 0 : part(m_partsByMime[mimeType.latin1()]);
00191 }
00192 
00193 Info *
00194 Manager::infoForMimeType(const QString &mimeType)
00195 {
00196     Info *i = mimeType.isEmpty() ? 0 : m_partsByMime[mimeType.latin1()];
00197     if (i)
00198         return i;
00199     setError(i18n("No plugin for mime type \"%1\"").arg(mimeType));
00200     return 0;
00201 }
00202 
00203 
00204 bool
00205 Manager::checkProject(KexiDB::Connection *conn)
00206 {
00207     clearError();
00208 //  QString errmsg = i18n("Invalid project contents.");
00209 
00210 //TODO: catch errors!
00211     if(!conn->isDatabaseUsed()) {
00212         setError(conn);
00213         return false;
00214     }
00215 
00216     KexiDB::Cursor *cursor = conn->executeQuery("SELECT * FROM kexi__parts");//, KexiDB::Cursor::Buffered);
00217     if(!cursor) {
00218         setError(conn);
00219         return false;
00220     }
00221 
00222 //  int id=0;
00223 //  QStringList parts_found;
00224     for(cursor->moveFirst(); !cursor->eof(); cursor->moveNext())
00225     {
00226 //      id++;
00227         Info *i = infoForMimeType(cursor->value(2).toCString());
00228         if(!i)
00229         {
00230             Missing m;
00231             m.name = cursor->value(1).toString();
00232             m.mime = cursor->value(2).toCString();
00233             m.url = cursor->value(3).toString();
00234 
00235             m_missing.append(m);
00236         }
00237         else
00238         {
00239             i->setProjectPartID(cursor->value(0).toInt());
00240             i->setIdStoredInPartDatabase(true);
00241 //          parts_found+=cursor->value(2).toString();
00242         }
00243     }
00244 
00245     conn->deleteCursor(cursor);
00246 
00247 #if 0 //js: moved to Connection::createDatabase()
00248     //add missing default part entries
00249     KexiDB::TableSchema *ts = conn->tableSchema("kexi__parts");
00250     if (!ts)
00251         return false;
00252     KexiDB::FieldList *fl = ts->subList("p_id", "p_name", "p_mime", "p_url");
00253     if (!fl)
00254         return false;
00255     if (!parts_found.contains("kexi/table")) {
00256         if (!conn->insertRecord(*fl, QVariant(1), QVariant("Tables"), QVariant("kexi/table"), QVariant("http://")))
00257             return false;
00258     }
00259     if (!parts_found.contains("kexi/query")) {
00260         if (!conn->insertRecord(*fl, QVariant(2), QVariant("Queries"), QVariant("kexi/query"), QVariant("http://")))
00261             return false;
00262     }
00263 #endif
00264     return true;
00265 }
00266 
00267 void Manager::insertStaticPart(StaticPart* part)
00268 {
00269     if (!part)
00270         return;
00271     part->info()->setProjectPartID(m_nextTempProjectPartID--); // temp. part id are -1, -2, and so on, 
00272     m_partlist.append(part->info());
00273     if (!part->info()->mimeType().isEmpty())
00274         m_partsByMime.insert(part->info()->mimeType(), part->info());
00275     m_parts.insert(part->info()->projectPartID(), part);
00276 }
00277 
00278 #include "kexipartmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys