00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kexipart.h"
00022 #include "kexipartinfo.h"
00023 #include "kexipartitem.h"
00024 #include "kexistaticpart.h"
00025 #include "kexidialogbase.h"
00026 #include "kexiviewbase.h"
00027
00028 #include "kexipartguiclient.h"
00029 #include "keximainwindow.h"
00030
00031 #include "kexi.h"
00032
00033 #include <kexidb/connection.h>
00034 #include <kexiutils/identifier.h>
00035 #include <kexiutils/utils.h>
00036
00037 #include <qwidgetstack.h>
00038
00039 #include <kiconloader.h>
00040 #include <kdebug.h>
00041 #include <kmessagebox.h>
00042
00043 namespace KexiPart {
00045 class PartPrivate
00046 {
00047 public:
00048 PartPrivate()
00049 : instanceActionsInitialized(false)
00050 {
00051 }
00052
00054 tristate askForOpeningInTextMode(KexiDialogBase *dlg, KexiPart::Item &item,
00055 int supportedViewModes, int viewMode)
00056 {
00057 if (viewMode != Kexi::TextViewMode
00058 && supportedViewModes & Kexi::TextViewMode
00059 && dlg->tempData()->proposeOpeningInTextViewModeBecauseOfProblems)
00060 {
00061
00062 KexiUtils::WaitCursorRemover remover;
00064 QString singleStatusString( dlg->singleStatusString() );
00065 if (!singleStatusString.isEmpty())
00066 singleStatusString.prepend(QString("\n\n")+futureI18n("Details:")+" ");
00067 if (KMessageBox::No==KMessageBox::questionYesNo(0,
00068 ((viewMode == Kexi::DesignViewMode)
00069 ? i18n("Object \"%1\" could not be opened in Design View.").arg(item.name())
00070 : i18n("Object could not be opened in Data View."))+"\n"
00071 + i18n("Do you want to open it in Text View?") + singleStatusString, 0,
00072 KStdGuiItem::open(), KStdGuiItem::cancel()))
00073 {
00074
00075 return false;
00076 }
00077 return true;
00078 }
00079 return cancelled;
00080 }
00081
00082 bool instanceActionsInitialized : 1;
00083 };
00084 }
00085
00086
00087
00088 using namespace KexiPart;
00089
00090 Part::Part(QObject *parent, const char *name, const QStringList &)
00091 : QObject(parent, name)
00092 , m_guiClient(0)
00093 , m_registeredPartID(-1)
00094 , d(new PartPrivate())
00095 {
00096 m_info = 0;
00097 m_supportedViewModes = Kexi::DataViewMode | Kexi::DesignViewMode;
00098 m_mainWin = 0;
00099 m_newObjectsAreDirty = false;
00100 }
00101
00102 Part::Part(QObject* parent, StaticInfo *info)
00103 : QObject(parent, "StaticPart")
00104 , m_guiClient(0)
00105 , m_registeredPartID(-1)
00106 , d(new PartPrivate())
00107 {
00108 m_info = info;
00109 m_supportedViewModes = Kexi::DesignViewMode;
00110 m_mainWin = 0;
00111 m_newObjectsAreDirty = false;
00112 }
00113
00114 Part::~Part()
00115 {
00116 delete d;
00117 }
00118
00119 void Part::createGUIClients(KexiMainWindow *win)
00120 {
00121 m_mainWin = win;
00122 if (!m_guiClient) {
00123
00124 m_guiClient = new GUIClient(m_mainWin, this, false, "part");
00125
00126
00127 KAction *act = new KAction(m_names["instanceCaption"]+"...", info()->createItemIcon(), 0, this,
00128 SLOT(slotCreate()), m_mainWin->actionCollection(),
00129 KexiPart::nameForCreateAction(*info()));
00130 act->plug( m_mainWin->findPopupMenu("insert") );
00131
00132
00133
00134
00135 m_mainWin->guiFactory()->addClient(m_guiClient);
00136
00137
00138
00139
00140
00141
00142
00143 for (int mode = 1; mode <= 0x01000; mode <<= 1) {
00144 if (m_supportedViewModes & mode) {
00145 GUIClient *instanceGuiClient = new GUIClient(m_mainWin,
00146 this, true, Kexi::nameForViewMode(mode).latin1());
00147 m_instanceGuiClients.insert(mode, instanceGuiClient);
00148
00149 }
00150 }
00151
00152 GUIClient *instanceGuiClient = new GUIClient(m_mainWin, this, true, "allViews");
00153 m_instanceGuiClients.insert(Kexi::AllViewModes, instanceGuiClient);
00154
00155
00156
00157 initPartActions();
00158
00159 }
00160 }
00161
00162 KActionCollection* Part::actionCollectionForMode(int viewMode) const
00163 {
00164 KXMLGUIClient *cli = m_instanceGuiClients[viewMode];
00165 return cli ? cli->actionCollection() : 0;
00166 }
00167
00168 KAction* Part::createSharedAction(int mode, const QString &text,
00169 const QString &pix_name, const KShortcut &cut, const char *name,
00170 const char *subclassName)
00171 {
00172 GUIClient *instanceGuiClient = m_instanceGuiClients[mode];
00173 if (!instanceGuiClient) {
00174 kdDebug() << "KexiPart::createSharedAction(): no gui client for mode " << mode << "!" << endl;
00175 return 0;
00176 }
00177 return m_mainWin->createSharedAction(text, pix_name, cut, name,
00178 instanceGuiClient->actionCollection(), subclassName);
00179 }
00180
00181 KAction* Part::createSharedPartAction(const QString &text,
00182 const QString &pix_name, const KShortcut &cut, const char *name,
00183 const char *subclassName)
00184 {
00185 if (!m_guiClient)
00186 return 0;
00187 return m_mainWin->createSharedAction(text, pix_name, cut, name,
00188 m_guiClient->actionCollection(), subclassName);
00189 }
00190
00191 KAction* Part::createSharedToggleAction(int mode, const QString &text,
00192 const QString &pix_name, const KShortcut &cut, const char *name)
00193 {
00194 return createSharedAction(mode, text, pix_name, cut, name, "KToggleAction");
00195 }
00196
00197 KAction* Part::createSharedPartToggleAction(const QString &text,
00198 const QString &pix_name, const KShortcut &cut, const char *name)
00199 {
00200 return createSharedPartAction(text, pix_name, cut, name, "KToggleAction");
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void Part::setActionAvailable(const char *action_name, bool avail)
00221 {
00222 QIntDictIterator<GUIClient> it( m_instanceGuiClients );
00223 for (;it.current();++it) {
00224 KAction *act = it.current()->actionCollection()->action(action_name);
00225 if (act) {
00226 act->setEnabled(avail);
00227 return;
00228 }
00229 }
00230
00231 m_mainWin->setActionAvailable(action_name, avail);
00232 }
00233
00234 KexiDialogBase* Part::openInstance(KexiMainWindow *win, KexiPart::Item &item, int viewMode,
00235 QMap<QString,QString>* staticObjectArgs)
00236 {
00237
00238 if (!d->instanceActionsInitialized) {
00239 initInstanceActions();
00240 d->instanceActionsInitialized = true;
00241 }
00242
00243 m_status.clearStatus();
00244
00245
00246
00247
00248 KexiDialogBase *dlg = new KexiDialogBase(win);
00249 dlg->m_supportedViewModes = m_supportedViewModes;
00250
00251
00252 dlg->m_part = this;
00253 dlg->m_item = &item;
00254 dlg->updateCaption();
00255
00256 KexiDB::SchemaData sdata(m_info->projectPartID());
00257 sdata.setName( item.name() );
00258 sdata.setCaption( item.caption() );
00259 sdata.setDescription( item.description() );
00260
00264
00265
00266 dlg->setId(item.identifier());
00267
00268 dlg->setIcon( SmallIcon( dlg->itemIcon() ) );
00269 if (dlg->mdiParent())
00270 dlg->mdiParent()->setIcon( *dlg->icon() );
00271
00272
00273 dlg->stack()->setIcon( *dlg->icon() );
00274 dlg->m_tempData = createTempData(dlg);
00275
00276 if (!item.neverSaved()) {
00277
00278 dlg->m_schemaData = loadSchemaData(dlg, sdata, viewMode);
00279 if (!dlg->m_schemaData) {
00280
00281 if (false == d->askForOpeningInTextMode(dlg, item, dlg->m_supportedViewModes, viewMode)) {
00282 delete dlg;
00283 return 0;
00284 }
00285 viewMode = Kexi::TextViewMode;
00286 dlg->m_schemaData = loadSchemaData(dlg, sdata, viewMode);
00287 }
00288 if (!dlg->m_schemaData) {
00289 if (!m_status.error())
00290 m_status = Kexi::ObjectStatus( dlg->mainWin()->project()->dbConnection(),
00291 i18n("Could not load object's definition."), i18n("Object design may be corrupted."));
00292 m_status.append(
00293 Kexi::ObjectStatus(i18n("You can delete \"%1\" object and create it again.")
00294 .arg(item.name()), QString::null) );
00295
00296 dlg->close();
00297 delete dlg;
00298 return 0;
00299 }
00300 }
00301
00302 bool switchingFailed = false;
00303 bool dummy;
00304 tristate res = dlg->switchToViewMode( viewMode, staticObjectArgs, dummy );
00305 if (!res) {
00306 tristate askForOpeningInTextModeRes
00307 = d->askForOpeningInTextMode(dlg, item, dlg->m_supportedViewModes, viewMode);
00308
00309
00310
00311 if (true == askForOpeningInTextModeRes) {
00312 delete dlg->m_schemaData;
00313 dlg->close();
00314 delete dlg;
00315
00316 return openInstance(win, item, Kexi::TextViewMode, staticObjectArgs);
00317 }
00318 else if (false == askForOpeningInTextModeRes) {
00319 delete dlg->m_schemaData;
00320 dlg->close();
00321 delete dlg;
00322 return 0;
00323 }
00324
00325 switchingFailed = true;
00326 }
00327 if (~res)
00328 switchingFailed = true;
00329
00330 if (switchingFailed) {
00331 m_status = dlg->status();
00332 dlg->close();
00333 delete dlg;
00334 return 0;
00335 }
00336 dlg->registerDialog();
00337 dlg->show();
00338
00339 if (dlg->mdiParent() && dlg->mdiParent()->state()==KMdiChildFrm::Normal)
00340 dlg->resize(dlg->sizeHint());
00341
00342 dlg->setMinimumSize(dlg->minimumSizeHint().width(),dlg->minimumSizeHint().height());
00343
00344
00345 if (dlg->selectedView())
00346 dlg->selectedView()->setDirty( m_newObjectsAreDirty ? item.neverSaved() : false );
00347
00348 return dlg;
00349 }
00350
00351 void Part::slotCreate()
00352 {
00353 emit newObjectRequest( m_info );
00354 }
00355
00356 KexiDB::SchemaData* Part::loadSchemaData(KexiDialogBase * , const KexiDB::SchemaData& sdata,
00357 int )
00358 {
00359 KexiDB::SchemaData *new_schema = new KexiDB::SchemaData();
00360 *new_schema = sdata;
00361 return new_schema;
00362 }
00363
00364 bool Part::loadDataBlock( KexiDialogBase *dlg, QString &dataString, const QString& dataID)
00365 {
00366 if (!dlg->mainWin()->project()->dbConnection()->loadDataBlock( dlg->id(), dataString, dataID )) {
00367 m_status = Kexi::ObjectStatus( dlg->mainWin()->project()->dbConnection(),
00368 i18n("Could not load object's data."), i18n("Data identifier: \"%1\".").arg(dataID) );
00369 m_status.append( *dlg );
00370 return false;
00371 }
00372 return true;
00373 }
00374
00375 void Part::initPartActions()
00376 {
00377 }
00378
00379 void Part::initInstanceActions()
00380 {
00381 }
00382
00383 bool Part::remove(KexiMainWindow *win, KexiPart::Item &item)
00384 {
00385 if (!win || !win->project() || !win->project()->dbConnection())
00386 return false;
00387 KexiDB::Connection *conn = win->project()->dbConnection();
00388 return conn->removeObject( item.identifier() );
00389 }
00390
00391 KexiDialogTempData* Part::createTempData(KexiDialogBase* dialog)
00392 {
00393 return new KexiDialogTempData(dialog);
00394 }
00395
00396 QString Part::i18nMessage(const QCString& englishMessage, KexiDialogBase* dlg) const
00397 {
00398 Q_UNUSED(dlg);
00399 return QString(englishMessage).startsWith(":") ? QString::null : englishMessage;
00400 }
00401
00402 void Part::setupCustomPropertyPanelTabs(KTabWidget *, KexiMainWindow*)
00403 {
00404 }
00405
00406 QCString Part::instanceName() const
00407 {
00408
00409
00410 return KexiUtils::string2Identifier(m_names["instanceName"]).lower().latin1();
00411 }
00412
00413 QString Part::instanceCaption() const
00414 {
00415 return m_names["instanceCaption"];
00416 }
00417
00418 tristate Part::rename(KexiMainWindow *win, KexiPart::Item &item, const QString& newName)
00419 {
00420 Q_UNUSED(win);
00421 Q_UNUSED(item);
00422 Q_UNUSED(newName);
00423 return true;
00424 }
00425
00426
00427
00428
00429 GUIClient::GUIClient(KexiMainWindow *win, Part* part, bool partInstanceClient, const char* nameSuffix)
00430 : QObject(part,
00431 (part->info()->objectName()
00432 + (nameSuffix ? QString(":%1").arg(nameSuffix) : QString())).latin1() )
00433 , KXMLGUIClient(win)
00434 {
00435 if(!win->project()->final())
00436 setXMLFile(QString::fromLatin1("kexi")+part->info()->objectName()
00437 +"part"+(partInstanceClient?"inst":"")+"ui.rc");
00438
00439
00440
00441
00442
00443
00444
00445
00446 }
00447
00448
00449 #include "kexipart.moc"
00450