00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kexidialogbase.h"
00022
00023 #include "keximainwindow.h"
00024 #include "kexiviewbase.h"
00025 #include "kexicontexthelp_p.h"
00026 #include "kexipart.h"
00027 #include "kexistaticpart.h"
00028 #include "kexipartitem.h"
00029 #include "kexipartinfo.h"
00030 #include "kexiproject.h"
00031
00032 #include <kexidb/connection.h>
00033 #include <kexidb/utils.h>
00034 #include <kexiutils/utils.h>
00035
00036 #include <qwidgetstack.h>
00037 #include <qobjectlist.h>
00038
00039 #include <kdebug.h>
00040 #include <kapplication.h>
00041 #include <kiconloader.h>
00042
00043 KexiDialogBase::KexiDialogBase(KexiMainWindow *parent, const QString &caption)
00044 : KMdiChildView(caption, parent, "KexiDialogBase")
00045 , KexiActionProxy(this, parent)
00046 , m_isRegistered(false)
00047 , m_origCaption(caption)
00048 , m_schemaData(0)
00049 , m_destroying(false)
00050 , m_disableDirtyChanged(false)
00051
00052 {
00053 m_supportedViewModes = 0;
00054 m_openedViewModes = 0;
00055 m_currentViewMode = Kexi::NoViewMode;
00056 m_parentWindow = parent;
00057 m_newlySelectedView = 0;
00058 m_creatingViewsMode = -1;
00059
00060 QVBoxLayout *lyr = new QVBoxLayout(this);
00061 m_stack = new QWidgetStack(this, "stack");
00062 lyr->addWidget(m_stack);
00063
00064 #ifdef KEXI_NO_CTXT_HELP
00065 m_contextHelpInfo=new KexiContextHelpInfo();
00066 #endif
00067
00068 m_id = -1;
00069 m_item = 0;
00070
00071 hide();
00072 }
00073
00074 KexiDialogBase::~KexiDialogBase()
00075 {
00076 m_destroying = true;
00077 }
00078
00079 KexiViewBase *KexiDialogBase::selectedView() const
00080 {
00081 if (m_destroying)
00082 return 0;
00083
00084 return static_cast<KexiViewBase*>( m_stack->widget(m_currentViewMode) );
00085 }
00086
00087 KexiViewBase *KexiDialogBase::viewForMode(int mode) const
00088 {
00089 return static_cast<KexiViewBase*>( m_stack->widget(mode) );
00090 }
00091
00092 void KexiDialogBase::addView(KexiViewBase *view)
00093 {
00094 addView(view,0);
00095 }
00096
00097 void KexiDialogBase::addView(KexiViewBase *view, int mode)
00098 {
00099 m_stack->addWidget(view, mode);
00100
00101
00102
00103 QWidget *ch = static_cast<QWidget*>(view->child( 0, "QWidget", false ));
00104 if (ch)
00105 view->setFocusProxy(ch);
00106
00107 m_openedViewModes |= mode;
00108 }
00109
00110 QSize KexiDialogBase::minimumSizeHint() const
00111 {
00112 KexiViewBase *v = selectedView();
00113 if (!v)
00114 return KMdiChildView::minimumSizeHint();
00115 return v->minimumSizeHint() + QSize(0, mdiParent() ? mdiParent()->captionHeight() : 0);
00116 }
00117
00118 QSize KexiDialogBase::sizeHint() const
00119 {
00120 KexiViewBase *v = selectedView();
00121 if (!v)
00122 return KMdiChildView::sizeHint();
00123 return v->preferredSizeHint( v->sizeHint() );
00124 }
00125
00126
00127
00128
00129
00130
00131 void KexiDialogBase::registerDialog() {
00132 if (m_isRegistered)
00133 return;
00134 m_parentWindow->registerChild(this);
00135 m_isRegistered=true;
00136 if ( m_parentWindow->mdiMode() == KMdi::ToplevelMode ) {
00137 m_parentWindow->addWindow( (KMdiChildView *)this, KMdi::Detach );
00138 m_parentWindow->detachWindow((KMdiChildView *)this, true);
00139 }
00140 else
00141 m_parentWindow->addWindow((KMdiChildView *)this);
00142
00143
00144 }
00145
00146 bool KexiDialogBase::isRegistered(){
00147 return m_isRegistered;
00148 }
00149
00150 void KexiDialogBase::attachToGUIClient() {
00151 if (!guiClient())
00152 return;
00153
00154 }
00155
00156 void KexiDialogBase::detachFromGUIClient() {
00157 if (!guiClient())
00158 return;
00159
00160 }
00161
00162 int KexiDialogBase::id() const
00163 {
00164 return (partItem() && partItem()->identifier()>0) ? partItem()->identifier() : m_id;
00165 }
00166
00167 void KexiDialogBase::setContextHelp(const QString& caption, const QString& text, const QString& iconName) {
00168 #ifdef KEXI_NO_CTXT_HELP
00169 m_contextHelpInfo->caption=caption;
00170 m_contextHelpInfo->text=text;
00171 m_contextHelpInfo->text=iconName;
00172 updateContextHelp();
00173 #endif
00174 }
00175
00176 void KexiDialogBase::closeEvent( QCloseEvent * e )
00177 {
00178 m_parentWindow->acceptPropertySetEditing();
00179
00180
00181 QObjectList *list = m_stack->queryList( "KexiViewBase", 0, false, false);
00182 KexiViewBase *view;
00183 QObjectListIt it( *list );
00184 for ( ;(view = static_cast<KexiViewBase*>(it.current()) ) != 0; ++it ) {
00185 bool cancel = false;
00186 emit view->closing(cancel);
00187 if (cancel) {
00188 e->ignore();
00189 return;
00190 }
00191 }
00192 delete list;
00193 emit closing();
00194 KMdiChildView::closeEvent(e);
00195 }
00196
00197 #if 0
00198
00199 bool KexiDialogBase::tryClose(bool dontSaveChanges)
00200 {
00201 if (!dontSaveChanges && dirty()) {
00202
00203
00204
00205
00206
00207 }
00208 close(true);
00209 return true;
00210 }
00211 #endif
00212
00213 bool KexiDialogBase::dirty() const
00214 {
00215
00216 int m = m_openedViewModes, mode = 1;
00217 while (m>0) {
00218 if (m & 1) {
00219 if (static_cast<KexiViewBase*>(m_stack->widget(mode))->dirty())
00220 return true;
00221 }
00222 m >>= 1;
00223 mode <<= 1;
00224 }
00225 return false;
00226
00227
00228 }
00229
00230 void KexiDialogBase::setDirty(bool dirty)
00231 {
00232 m_disableDirtyChanged = true;
00233 int m = m_openedViewModes, mode = 1;
00234 while (m>0) {
00235 if (m & 1) {
00236 static_cast<KexiViewBase*>(m_stack->widget(mode))->setDirty(dirty);
00237 }
00238 m >>= 1;
00239 mode <<= 1;
00240 }
00241 m_disableDirtyChanged = false;
00242 dirtyChanged();
00243 }
00244
00245 QString KexiDialogBase::itemIcon()
00246 {
00247 if (!m_part || !m_part->info()) {
00248 KexiViewBase *v = selectedView();
00249 if (v) {
00250 return v->m_defaultIconName;
00251 }
00252 return QString::null;
00253 }
00254 return m_part->info()->itemIcon();
00255 }
00256
00257 KexiPart::GUIClient* KexiDialogBase::guiClient() const
00258 {
00259 if (!m_part || m_currentViewMode<1)
00260 return 0;
00261 return m_part->instanceGuiClient(m_currentViewMode);
00262 }
00263
00264 KexiPart::GUIClient* KexiDialogBase::commonGUIClient() const
00265 {
00266 if (!m_part)
00267 return 0;
00268 return m_part->instanceGuiClient(0);
00269 }
00270
00271 tristate KexiDialogBase::switchToViewMode( int newViewMode, QMap<QString,QString>* staticObjectArgs )
00272 {
00273 m_parentWindow->acceptPropertySetEditing();
00274
00275 const bool designModePreloadedForTextModeHack =
00276 newViewMode==Kexi::TextViewMode
00277 && !viewForMode(Kexi::DesignViewMode)
00278 && supportsViewMode(Kexi::DesignViewMode);
00279
00280 tristate res = true;
00281 if (designModePreloadedForTextModeHack) {
00282
00283 res = switchToViewMode( Kexi::DesignViewMode, staticObjectArgs );
00284 if (!res || ~res)
00285 return res;
00286 }
00287
00288 kdDebug() << "KexiDialogBase::switchToViewMode()" << endl;
00289 bool dontStore = false;
00290 KexiViewBase *view = selectedView();
00291
00292 if (m_currentViewMode == newViewMode)
00293 return true;
00294 if (!supportsViewMode(newViewMode))
00295 return false;
00296
00297 if (view) {
00298 res = true;
00299 if (!designModePreloadedForTextModeHack) {
00300 res = view->beforeSwitchTo(newViewMode, dontStore);
00301 }
00302 if (~res || !res)
00303 return res;
00304 if (!dontStore && view->dirty()) {
00305 res = m_parentWindow->saveObject(this, i18n("Design has been changed. "
00306 "You must save it before switching to other view."));
00307 if (~res || !res)
00308 return res;
00309
00310
00311 }
00312 }
00313
00314
00315 KexiViewBase *newView
00316 = (m_stack->widget(newViewMode) && m_stack->widget(newViewMode)->inherits("KexiViewBase"))
00317 ? static_cast<KexiViewBase*>(m_stack->widget(newViewMode)) : 0;
00318 if (!newView) {
00319 KexiUtils::setWaitCursor();
00320
00321 m_creatingViewsMode = newViewMode;
00322 KexiPart::StaticPart *staticPart = dynamic_cast<KexiPart::StaticPart*>((KexiPart::Part*)m_part);
00323 if (staticPart)
00324 newView = staticPart->createView(m_stack, this, *m_item, newViewMode, staticObjectArgs);
00325 else
00326 newView = m_part->createView(m_stack, this, *m_item, newViewMode, staticObjectArgs);
00327 KexiUtils::removeWaitCursor();
00328 if (!newView) {
00329
00330 kdDebug() << "Switching to mode " << newViewMode << " failed. Previous mode "
00331 << m_currentViewMode << " restored." << endl;
00332 return false;
00333 }
00334 m_creatingViewsMode = -1;
00335 addView(newView, newViewMode);
00336 }
00337 const int prevViewMode = m_currentViewMode;
00338 res = true;
00339 if (designModePreloadedForTextModeHack) {
00340 m_currentViewMode = Kexi::NoViewMode;
00341 }
00342 res = newView->beforeSwitchTo(newViewMode, dontStore);
00343 if (!res) {
00344 kdDebug() << "Switching to mode " << newViewMode << " failed. Previous mode "
00345 << m_currentViewMode << " restored." << endl;
00346 return false;
00347 }
00348 m_currentViewMode = newViewMode;
00349 m_newlySelectedView = newView;
00350 if (prevViewMode==Kexi::NoViewMode)
00351 m_newlySelectedView->setDirty(false);
00352
00353 res = newView->afterSwitchFrom(
00354 designModePreloadedForTextModeHack ? Kexi::NoViewMode : prevViewMode);
00355 if (!res) {
00356 kdDebug() << "Switching to mode " << newViewMode << " failed. Previous mode "
00357 << prevViewMode << " restored." << endl;
00358 m_currentViewMode = prevViewMode;
00359 return false;
00360 }
00361 m_newlySelectedView = 0;
00362 if (~res) {
00363 m_currentViewMode = prevViewMode;
00364 return cancelled;
00365 }
00366 if (view)
00367 takeActionProxyChild( view );
00368 addActionProxyChild( newView );
00369 m_stack->raiseWidget( newView );
00370 newView->propertySetSwitched();
00371 m_parentWindow->invalidateSharedActions( newView );
00372
00373 return true;
00374 }
00375
00376 tristate KexiDialogBase::switchToViewMode( int newViewMode )
00377 {
00378 return switchToViewMode( newViewMode, 0 );
00379 }
00380
00381 void KexiDialogBase::setFocus()
00382 {
00383 if (m_stack->visibleWidget()) {
00384 if (m_stack->visibleWidget()->inherits("KexiViewBase"))
00385 static_cast<KexiViewBase*>( m_stack->visibleWidget() )->setFocus();
00386 else
00387 m_stack->visibleWidget()->setFocus();
00388 }
00389 else {
00390 KMdiChildView::setFocus();
00391 }
00392 activate();
00393 }
00394
00395 KoProperty::Set*
00396 KexiDialogBase::propertySet()
00397 {
00398 KexiViewBase *v = selectedView();
00399 if (!v)
00400 return 0;
00401 return v->propertySet();
00402 }
00403
00404 bool KexiDialogBase::eventFilter(QObject *obj, QEvent *e)
00405 {
00406 if (KMdiChildView::eventFilter(obj, e))
00407 return true;
00408
00409
00410
00411
00412 if ((e->type()==QEvent::FocusIn && m_parentWindow->activeWindow()==this)
00413 || e->type()==QEvent::MouseButtonPress) {
00414 if (m_stack->visibleWidget() && KexiUtils::hasParent(m_stack->visibleWidget(), obj)) {
00415
00416 activate();
00417 }
00418 }
00419 return false;
00420 }
00421
00422 void KexiDialogBase::dirtyChanged()
00423 {
00424 if (m_disableDirtyChanged)
00425 return;
00426
00427
00428
00429
00430
00431
00432
00433
00434 updateCaption();
00435 emit dirtyChanged(this);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void KexiDialogBase::updateCaption()
00448 {
00449 if (!m_item || !m_part || !m_origCaption.isEmpty())
00450 return;
00451
00452 QString capt = m_item->name();
00453 QString fullCapt = capt;
00454 if (m_part)
00455 fullCapt += (" : " + m_part->instanceCaption());
00456 if (dirty()) {
00457 KMdiChildView::setCaption(fullCapt+"*");
00458 KMdiChildView::setTabCaption(capt+"*");
00459 }
00460 else {
00461 KMdiChildView::setCaption(fullCapt);
00462 KMdiChildView::setTabCaption(capt);
00463 }
00464 }
00465
00466 bool KexiDialogBase::neverSaved() const
00467 {
00468 return m_item ? m_item->neverSaved() : true;
00469 }
00470
00471 tristate KexiDialogBase::storeNewData()
00472 {
00473 if (!neverSaved())
00474 return false;
00475 KexiViewBase *v = selectedView();
00476 if (m_schemaData)
00477 return false;
00478 if (!v)
00479 return false;
00480
00481 KexiDB::SchemaData sdata(m_part->info()->projectPartID());
00482 sdata.setName( m_item->name() );
00483 sdata.setCaption( m_item->caption() );
00484 sdata.setDescription( m_item->description() );
00485
00486 bool cancel = false;
00487 m_schemaData = v->storeNewData(sdata, cancel);
00488 if (cancel)
00489 return cancelled;
00490 if (!m_schemaData) {
00491 setStatus(m_parentWindow->project()->dbConnection(), i18n("Saving object's definition failed."),"");
00492 return false;
00493 }
00494
00495 if (!part()->info()->isIdStoredInPartDatabase()) {
00496
00497 KexiDB::TableSchema *ts = m_parentWindow->project()->dbConnection()->tableSchema("kexi__parts");
00498 kdDebug() << "KexiMainWindowImpl::newObject(): schema: " << ts << endl;
00499 if (!ts)
00500 return false;
00501
00502
00503
00504 int p_id = part()->info()->projectPartID();
00505
00506 if (p_id<0) {
00507
00508
00509 p_id = (int)KexiPart::UserObjectType;
00510 tristate success = m_parentWindow->project()->dbConnection()->querySingleNumber(
00511 "SELECT max(p_id) FROM kexi__parts", p_id);
00512 if (!success) {
00513
00514 return false;
00515 } else {
00516
00517 p_id = p_id + 1;
00518 p_id = QMAX(p_id, (int)KexiPart::UserObjectType);
00519 }
00520 }
00521
00522 KexiDB::FieldList *fl = ts->subList("p_id", "p_name", "p_mime", "p_url");
00523 kexidbg << "KexiMainWindowImpl::newObject(): fieldlist: "
00524 << (fl ? fl->debugString() : QString::null) << endl;
00525 if (!fl)
00526 return false;
00527
00528 kexidbg << part()->info()->ptr()->untranslatedGenericName() << endl;
00529
00530
00531
00532 if (!m_parentWindow->project()->dbConnection()->insertRecord(
00533 *fl,
00534 QVariant(p_id),
00535 QVariant(part()->info()->ptr()->untranslatedGenericName()),
00536 QVariant(part()->info()->mimeType()), QVariant("http://www.koffice.org/kexi/" )))
00537 return false;
00538
00539 kdDebug() << "KexiMainWindowImpl::newObject(): insert success!" << endl;
00540 part()->info()->setProjectPartID( p_id );
00541
00542 kdDebug() << "KexiMainWindowImpl::newObject(): new id is: "
00543 << part()->info()->projectPartID() << endl;
00544
00545 part()->info()->setIdStoredInPartDatabase(true);
00546 }
00547
00548
00549 setDirty(false);
00550
00551
00552
00553 m_item->setIdentifier( m_schemaData->id() );
00554 m_parentWindow->project()->addStoredItem( part()->info(), m_item );
00555
00556 return true;
00557 }
00558
00559 tristate KexiDialogBase::storeData(bool dontAsk)
00560 {
00561 if (neverSaved())
00562 return false;
00563 KexiViewBase *v = selectedView();
00564 if (!v)
00565 return false;
00566
00567 #define storeData_ERR \
00568 setStatus(m_parentWindow->project()->dbConnection(), i18n("Saving object's data failed."),"");
00569
00570
00571 KexiDB::Transaction transaction = m_parentWindow->project()->dbConnection()->beginTransaction();
00572 if (transaction.isNull()) {
00573 storeData_ERR;
00574 return false;
00575 }
00576 KexiDB::TransactionGuard tg(transaction);
00577
00578 const tristate res = v->storeData(dontAsk);
00579 if (~res)
00580 return res;
00581 if (!res) {
00582 storeData_ERR;
00583 return res;
00584 }
00585 if (!tg.commit()) {
00586 storeData_ERR;
00587 return false;
00588 }
00589
00590 setDirty(false);
00591
00592 return true;
00593 }
00594
00595 void KexiDialogBase::activate()
00596 {
00597 KexiViewBase *v = selectedView();
00598
00599 if (KexiUtils::hasParent( v, KMdiChildView::focusedChildWidget()))
00600 KMdiChildView::activate();
00601 else {
00602 if (v)
00603 v->setFocus();
00604 }
00605 if (v)
00606 v->updateActions(true);
00607
00608 }
00609
00610 void KexiDialogBase::deactivate()
00611 {
00612 KexiViewBase *v = selectedView();
00613 if (v)
00614 v->updateActions(false);
00615 }
00616
00617 void KexiDialogBase::sendDetachedStateToCurrentView()
00618 {
00619 KexiViewBase *v = selectedView();
00620 if (v)
00621 v->parentDialogDetached();
00622 }
00623
00624 void KexiDialogBase::sendAttachedStateToCurrentView()
00625 {
00626 KexiViewBase *v = selectedView();
00627 if (v)
00628 v->parentDialogAttached();
00629 }
00630
00631 #include "kexidialogbase.moc"
00632