kexi

keximainwindowimpl.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
00003    Copyright (C) 2003-2007 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 "keximainwindowimpl.h"
00022 
00023 #include <unistd.h>
00024 
00025 #include <qapplication.h>
00026 #include <qeventloop.h>
00027 #include <qfile.h>
00028 #include <qtimer.h>
00029 #include <qobjectlist.h>
00030 #include <qprocess.h>
00031 #include <qtoolbutton.h>
00032 #include <qtooltip.h>
00033 #include <qmutex.h>
00034 #include <qwaitcondition.h>
00035 #include <qfiledialog.h>
00036 #include <qdockwindow.h>
00037 #include <qdockarea.h>
00038 
00039 #include <kapplication.h>
00040 #include <kcmdlineargs.h>
00041 #include <kaction.h>
00042 #include <klocale.h>
00043 #include <kstdaccel.h>
00044 #include <kconfig.h>
00045 #include <kglobal.h>
00046 #include <kdebug.h>
00047 #include <kkeydialog.h>
00048 #include <kedittoolbar.h>
00049 #include <kdeversion.h>
00050 #include <kglobalsettings.h>
00051 #include <kparts/componentfactory.h>
00052 #include <ktip.h>
00053 #include <kstandarddirs.h>
00054 #include <kpushbutton.h>
00055 #include <ktextbrowser.h>
00056 #include <kiconloader.h>
00057 #include <ktabwidget.h>
00058 #include <kimageio.h>
00059 #include <khelpmenu.h>
00060 #include <kfiledialog.h>
00061 #include <krecentdocument.h>
00062 
00063 #include <kexidb/connection.h>
00064 #include <kexidb/utils.h>
00065 #include <kexidb/cursor.h>
00066 #include <kexidb/dbobjectnamevalidator.h>
00067 #include <kexidb/admin.h>
00068 #include <kexiutils/utils.h>
00069 
00070 //#include "projectsettingsui.h"
00071 #include "kexiactionproxy.h"
00072 #include "kexidialogbase.h"
00073 #include "kexipartmanager.h"
00074 #include "kexipart.h"
00075 #include "kexipartinfo.h"
00076 #include "kexipartguiclient.h"
00077 #include "kexiproject.h"
00078 #include "kexiprojectdata.h"
00079 #include "kexiprojectset.h"
00080 #include "kexi.h"
00081 #include "kexistatusbar.h"
00082 #include "kexiinternalpart.h"
00083 #include "kexiactioncategories.h"
00084 #include "kexifinddialog.h"
00085 #include "kexisearchandreplaceiface.h"
00086 
00087 #include "kde2_closebutton.xpm"
00088 
00089 #include <widget/kexibrowser.h>
00090 #include <widget/kexipropertyeditorview.h>
00091 #include <widget/utils/kexirecordnavigator.h>
00092 #include <koproperty/editor.h>
00093 #include <koproperty/set.h>
00094 
00095 #include "startup/KexiStartup.h"
00096 #include "startup/KexiNewProjectWizard.h"
00097 #include "startup/KexiStartupDialog.h"
00098 #include "startup/KexiStartupFileDialog.h"
00099 #include "kexinamedialog.h"
00100 #include "printing/kexisimpleprintingpart.h"
00101 #include "printing/kexisimpleprintingpagesetup.h"
00102 
00103 //Extreme verbose debug
00104 #if defined(Q_WS_WIN)
00105 # include <krecentdirs.h>
00106 # include <win32_utils.h>
00107 //# define KexiVDebug kdDebug()
00108 #endif
00109 
00110 #if !defined(KexiVDebug)
00111 # define KexiVDebug if (0) kdDebug()
00112 #endif
00113 
00114 //first fix the geometry
00115 //#define KEXI_NO_CTXT_HELP 1
00116 
00117 #ifndef KEXI_NO_CTXT_HELP
00118 #include <kexicontexthelp.h>
00119 #endif
00120 
00121 #ifdef HAVE_KNEWSTUFF
00122 #include <knewstuff/downloaddialog.h>
00123 #include "kexinewstuff.h"
00124 #endif
00125 
00128 //#define PROPEDITOR_VISIBILITY_CHANGES
00129 
00130 //temporary fix to manage layout
00131 #include "ksplitter.h"
00132 #define KDOCKWIDGET_P 1
00133 
00134 #ifndef KEXI_NO_FEEDBACK_AGENT
00135 #ifdef FEEDBACK_INCLUDE
00136 #include FEEDBACK_INCLUDE
00137 #endif
00138 #include <kapplication.h>
00139 #include <kaboutdata.h>
00140 #endif
00141 
00142 #include "keximainwindowimpl_p.h"
00143 
00144 //-------------------------------------------------
00145 
00146 //static
00147 int KexiMainWindowImpl::create(int argc, char *argv[], KAboutData* aboutdata)
00148 {
00149     Kexi::initCmdLineArgs( argc, argv, aboutdata );
00150 
00151     bool GUIenabled = true;
00152     QWidget *dummyWidget = 0; //needed to have icon for dialogs before KexiMainWindowImpl is created
00154     KApplication* app = new KApplication(true, GUIenabled);
00155 
00156 #ifdef KEXI_STANDALONE
00157     KGlobal::locale()->removeCatalogue("kexi");
00158     KGlobal::locale()->insertCatalogue("standalone_kexi");
00159 #endif
00160     KGlobal::locale()->insertCatalogue("koffice");
00161     KGlobal::locale()->insertCatalogue("koproperty");
00162 
00163 #ifdef CUSTOM_VERSION
00164 # include "custom_exec.h"
00165 #endif
00166 
00167 #ifdef KEXI_DEBUG_GUI
00168     QWidget* debugWindow = 0;
00169 #endif
00170     if (GUIenabled) {
00171         dummyWidget = new QWidget();
00172         dummyWidget->setIcon( DesktopIcon( "kexi" ) );
00173         app->setMainWidget(dummyWidget);
00174 #ifdef KEXI_DEBUG_GUI
00175         app->config()->setGroup("General");
00176         if (app->config()->readBoolEntry("showInternalDebugger", false)) {
00177             debugWindow = KexiUtils::createDebugWindow(0);
00178         }
00179 #endif
00180     }
00181 
00182     tristate res = Kexi::startupHandler().init(argc, argv);
00183     if (!res || ~res) {
00184 #ifdef KEXI_DEBUG_GUI
00185         delete debugWindow;
00186 #endif
00187         delete app;
00188         return (~res) ? 0 : 1;
00189     }
00190     
00191     kdDebug() << "startupActions OK" <<endl;
00192 
00193     /* Exit requested, e.g. after database removing. */
00194     if (Kexi::startupHandler().action() == KexiStartupData::Exit) {
00195 #ifdef KEXI_DEBUG_GUI
00196         delete debugWindow;
00197 #endif
00198         delete app;
00199         return 0;
00200     }
00201 
00202     KexiMainWindowImpl *win = new KexiMainWindowImpl();
00203     app->setMainWidget(win);
00204 #ifdef KEXI_DEBUG_GUI
00205     //if (debugWindow)
00206         //debugWindow->reparent(win, QPoint(1,1));
00207 #endif
00208     delete dummyWidget;
00209 
00210     if (true != win->startup()) {
00211         delete win;
00212         delete app;
00213         return 1;
00214     }
00215 
00216     win->show();
00217     app->processEvents();//allow refresh our app
00218 
00219 //#ifdef KEXI_DEBUG_GUI
00220 //  delete debugWindow;
00221 //#endif
00222     return 0;
00223 }
00224 
00225 //-------------------------------------------------
00226 
00227 KexiMainWindowImpl::KexiMainWindowImpl()
00228  : KexiMainWindow()
00229  , KexiGUIMessageHandler(this)
00230  , d(new KexiMainWindowImpl::Private(this) )
00231 {
00232     KImageIO::registerFormats();
00233     KexiProjectData *pdata = Kexi::startupHandler().projectData();
00234     d->userMode = Kexi::startupHandler().forcedUserMode() /* <-- simply forced the user mode */
00235         /* project has 'user mode' set as default and not 'design mode' override is found: */
00236         || (pdata && pdata->userMode() && !Kexi::startupHandler().forcedDesignMode());
00237     d->isProjectNavigatorVisible = Kexi::startupHandler().isProjectNavigatorVisible();
00238 
00239     if(userMode())
00240         kdDebug() << "KexiMainWindowImpl::KexiMainWindowImpl(): starting up in the User Mode" << endl;
00241 
00242     d->config = kapp->config();
00243 
00244     if ( !initialGeometrySet() ) {
00245         int scnum = QApplication::desktop()->screenNumber(parentWidget());
00246         QRect desk = QApplication::desktop()->screenGeometry(scnum);
00247         d->config->setGroup("MainWindow");
00248         QSize s ( d->config->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 700 ),
00249             d->config->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 480 ) );
00250         resize (kMin (s.width(), desk.width()), kMin(s.height(), desk.height()));
00251     }
00252 
00253     setManagedDockPositionModeEnabled(true);//TODO(js): remove this if will be default in kmdi :)
00254     manager()->setSplitterHighResolution(true);
00255     manager()->setSplitterKeepSize(true);
00256     setStandardMDIMenuEnabled(false);
00257     setAsDefaultHost(); //this is default host now.
00258     KGlobal::iconLoader()->addAppDir("kexi");
00259     KGlobal::iconLoader()->addAppDir("koffice");
00260 
00261     //get informed
00262     connect(&Kexi::partManager(),SIGNAL(partLoaded(KexiPart::Part*)),this,SLOT(slotPartLoaded(KexiPart::Part*)));
00263     connect( m_pMdi, SIGNAL(nowMaximized(bool)), this, SLOT(slotCaptionForCurrentMDIChild(bool)) );
00264     connect( m_pMdi, SIGNAL(noMaximizedChildFrmLeft(KMdiChildFrm*)), this, SLOT(slotNoMaximizedChildFrmLeft(KMdiChildFrm*)));
00265 //  connect( this, SIGNAL(lastChildFrmClosed()), this, SLOT(slotLastChildFrmClosed()));
00266     connect( this, SIGNAL(lastChildViewClosed()), this, SLOT(slotLastChildViewClosed()));
00267 
00268     connect( this, SIGNAL(childViewIsDetachedNow(QWidget*)), this, SLOT(slotChildViewIsDetachedNow(QWidget*)));
00269     connect( this, SIGNAL(mdiModeHasBeenChangedTo(KMdi::MdiMode)),
00270         this, SLOT(slotMdiModeHasBeenChangedTo(KMdi::MdiMode)));
00271 
00272 
00273     //if (!userMode()) {
00274         setXMLFile("kexiui.rc");
00275         setAcceptDrops(true);
00276         initActions();
00277         createShellGUI(true);
00278     //}
00279 
00280     d->statusBar = new KexiStatusBar(this, "status_bar");
00281 
00282     d->origAppCaption = caption();
00283 
00284     restoreSettings();
00285     (void)Kexi::smallFont(this/*init*/);
00286 
00287     if (!userMode()) {
00288         initContextHelp();
00289         initPropertyEditor();
00290     }
00291 
00292     {//store menu popups list
00293         QObjectList *l = queryList( "QPopupMenu" );
00294         for (QObjectListIt it( *l ); it.current(); ++it ) {
00295             //kdDebug() << "name=" <<it.current()->name() << " cname="<<it.current()->className()<<endl;
00296             //KexiMainWindowImpl::eventFilter() will filter our popups:
00297             it.current()->installEventFilter(this);
00298             d->popups.insert(it.current()->name(), static_cast<QPopupMenu*>(it.current()));
00299         }
00300         delete l;
00301         d->createMenu = d->popups["create"];
00302 
00303 #ifdef KEXI_NO_REPORTBUG_COMMAND
00304         //remove "bug report" action to avoid confusion for supported with commercial technical support
00305         QPopupMenu *helpMenu = d->popups["help"];
00306         if (helpMenu) {
00307             //const int idx = helpMenu->indexOf( (int)KHelpMenu::menuReportBug );
00308             helpMenu->removeItemAt(int(KHelpMenu::menuReportBug)-1);
00309             helpMenu->removeItemAt(int(KHelpMenu::menuReportBug)-1); //separator
00310         }
00311 #endif
00312     }
00313 
00314     //fix menus a bit more:
00315 #ifndef KEXI_SHOW_UNIMPLEMENTED
00316 //disabled (possible crash) d->hideMenuItem("file", i18n("&Import"), true);
00317 //disabled (possible crash) d->hideMenuItem("help", i18n( "&Report Bug..." ), true);
00318 #endif
00319     KAction *kmdi_tooldock_menu_action = childClients()->getFirst() ? childClients()->getFirst()->actionCollection()->action("kmdi_tooldock_menu") : 0;
00320     if (kmdi_tooldock_menu_action) {
00321         kmdi_tooldock_menu_action->setEnabled(false);
00322     }
00323 
00324     if (!isFakingSDIApplication()/* && !userMode()*/) {
00325 //      QPopupMenu *menu = (QPopupMenu*) child( "window", "KPopupMenu" );
00326         QPopupMenu *menu = d->popups["window"];
00327         unsigned int count = menuBar()->count();
00328         if (menu)
00329             setWindowMenu(menu);
00330         else
00331             menuBar()->insertItem( i18n("&Window"), windowMenu(), -1, count-2); // standard position is left to the last ('Help')
00332     }
00333     if (userMode()) {
00334         //hide "insert" menu and disable "project_import", "edit_paste_special" menus
00335         QPopupMenu *menu = d->popups["insert"];
00336         if (menu) {
00337             for (uint i=0; i < menuBar()->count(); i++) {
00338                 if (menuBar()->text( menuBar()->idAt(i) ) == i18n("&Insert")) {
00339                     menuBar()->setItemVisible( menuBar()->idAt(i), false );
00340                     break;
00341                 }
00342             }
00343         }
00344         d->disableMenuItem("file", i18n("&Import"));
00345         d->disableMenuItem("edit", i18n("Paste &Special"));
00346     }
00347 
00348     m_pTaskBar->setCaption(i18n("Task Bar"));   //js TODO: move this to KMDIlib
00349 
00350 //  if (!userMode()) {
00351         invalidateActions();
00352         d->timer.singleShot(0,this,SLOT(slotLastActions()));
00353 //  }
00354 
00355     setTabWidgetVisibility(KMdi::AlwaysShowTabs);
00356     if (mdiMode()==KMdi::IDEAlMode) {
00357         d->config->setGroup("MainWindow");
00358         tabWidget()->setHoverCloseButton(d->config->readBoolEntry("HoverCloseButtonForTabs", false));
00359         //create special close button as corner widget for IDEAl mode
00360         QToolButton *closeButton = new QToolButton( tabWidget() );
00361         closeButton->setAutoRaise( true );
00362         closeButton->setPixmap( QPixmap( kde2_closebutton ) );
00363         closeButton->setPaletteBackgroundColor(closeButton->palette().active().background()); 
00364 //      closeButton->setIconSet(SmallIconSet("tab_remove"));
00365         tabWidget()->setCornerWidget( closeButton, Qt::TopRight );
00366         closeButton->hide(); // hide until it's needed to avoid problems in "user mode" 
00367                              // when initially the main window is empty
00368         QToolTip::add(closeButton, 
00369             i18n("Close the current tab page in Kexi tab interface", "Close the current tab"));
00370         QObject::connect( closeButton, SIGNAL( clicked() ), this, SLOT( closeActiveView() ) );
00371     }
00372 
00373 #ifdef KEXI_ADD_CUSTOM_KEXIMAINWINDOWIMPL
00374 # include "keximainwindowimpl_ctor.h"
00375 #endif
00376 }
00377 
00378 KexiMainWindowImpl::~KexiMainWindowImpl()
00379 {
00380     d->forceDialogClosing=true;
00381     closeProject();
00382     delete d;
00383 }
00384 
00385 KexiProject *KexiMainWindowImpl::project()
00386 {
00387     return d->prj;
00388 }
00389 
00390 void KexiMainWindowImpl::setWindowMenu(QPopupMenu *menu)
00391 {
00392     delete m_pWindowMenu;
00393     m_pWindowMenu = menu;
00394     int count = menuBar()->count();
00395     //try to move "window" menu just before "Settings" menu (count-3)
00396     const QString txt = i18n("&Window");
00397     int i;
00398     for (i=0; i<count; i++) {
00399         //kdDebug() << menuBar()->text( menuBar()->idAt(i) ) << endl;
00400         if (txt==menuBar()->text( menuBar()->idAt(i) ))
00401             break;
00402     }
00403     if (i<count) {
00404         const int id = menuBar()->idAt(i);
00405         menuBar()->removeItemAt(i);
00406         menuBar()->insertItem(txt, m_pWindowMenu, id, count-3);
00407     }
00408     m_pWindowMenu->setCheckable(true);
00409     QObject::connect( m_pWindowMenu, SIGNAL(aboutToShow()), this, SLOT(fillWindowMenu()) );
00410 }
00411 
00412 void KexiMainWindowImpl::fillWindowMenu()
00413 {
00414     KexiMainWindow::fillWindowMenu();
00415 
00416 /*  int i;
00417     for (i=0; i < (int)m_pWindowMenu->count(); i++) {
00418         if (m_pWindowMenu->text( m_pWindowMenu->idAt( i ) ) == i18n( "&MDI Mode" )) {
00419 //          kdDebug() << m_pWindowMenu->text( m_pWindowMenu->idAt( i ) ) << endl;
00420             m_pWindowMenu->removeItem( m_pWindowMenu->idAt( i ) );
00421             break;
00422         }
00423     }*/
00424 
00425     m_pMdiModeMenu->removeItem( m_pMdiModeMenu->idAt( 0 ) ); //hide toplevel mode
00426     m_pMdiModeMenu->removeItem( m_pMdiModeMenu->idAt( 1 ) ); //hide tabbed mode
00427     //update
00428     if (d->mdiModeToSwitchAfterRestart != (KMdi::MdiMode)0) {
00429         m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 0 ), 
00430             d->mdiModeToSwitchAfterRestart == KMdi::ChildframeMode );
00431         m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 1 ), 
00432             d->mdiModeToSwitchAfterRestart == KMdi::IDEAlMode );
00433     }
00434 
00435     //insert window_next, window_previous actions:
00436 //  const QString t = i18n("&Dock/Undock...");
00437     int i = m_pWindowMenu->count()-1;
00438     for (int index;; i--) {
00439         index = m_pWindowMenu->idAt(i);
00440         if (index==-1 || m_pWindowMenu->text(index).isNull())
00441                 break;
00442     }
00443     i++;
00444     d->action_window_next->plug( m_pWindowMenu, i++ );
00445     d->action_window_previous->plug( m_pWindowMenu, i++ );
00446     if (!m_pDocumentViews->isEmpty())
00447         m_pWindowMenu->insertSeparator( i++ );
00448 }
00449 
00450 void KexiMainWindowImpl::switchToIDEAlMode()
00451 {
00452     switchToIDEAlMode(true);
00453 }
00454 
00455 void KexiMainWindowImpl::switchToIDEAlMode(bool showMessage)
00456 {
00457     if (showMessage) {
00458         if ((int)d->mdiModeToSwitchAfterRestart == 0 && mdiMode()==KMdi::IDEAlMode)
00459             return;
00460         if (d->mdiModeToSwitchAfterRestart == KMdi::IDEAlMode)
00461             return;
00462         if (mdiMode()==KMdi::IDEAlMode) {//current mode
00463             d->mdiModeToSwitchAfterRestart = (KMdi::MdiMode)0;
00464         }
00465         else {
00466             KMessageBox::information(this,
00467                 i18n("User interface mode will be switched to IDEAl at next %1 application startup.")
00468                 .arg(KEXI_APP_NAME));
00469             //delayed
00470             d->mdiModeToSwitchAfterRestart = KMdi::IDEAlMode;
00471         }
00472     }
00473     else
00474         KexiMainWindow::switchToIDEAlMode();
00475 }
00476 
00477 void KexiMainWindowImpl::switchToChildframeMode()
00478 {
00479     switchToChildframeMode(true);
00480 }
00481 
00482 void KexiMainWindowImpl::switchToChildframeMode(bool showMessage)
00483 {
00484     if (showMessage) {
00485         if ((int)d->mdiModeToSwitchAfterRestart == 0 && mdiMode()==KMdi::ChildframeMode)
00486             return;
00487         if (d->mdiModeToSwitchAfterRestart == KMdi::ChildframeMode)
00488             return;
00489         if (mdiMode()==KMdi::ChildframeMode) {//current mode
00490             d->mdiModeToSwitchAfterRestart = (KMdi::MdiMode)0;
00491         }
00492         else {
00493             KMessageBox::information(this,
00494                 i18n("User interface mode will be switched to Childframe at next %1 application startup.")
00495                 .arg(KEXI_APP_NAME));
00496             //delayed
00497             d->mdiModeToSwitchAfterRestart = KMdi::ChildframeMode;
00498         }
00499     }
00500     else
00501         KexiMainWindow::switchToChildframeMode();
00502 }
00503 
00504 QPopupMenu* KexiMainWindowImpl::findPopupMenu(const char *popupName)
00505 {
00506     return d->popups[popupName];
00507 }
00508 
00509 KActionPtrList KexiMainWindowImpl::allActions() const
00510 {
00511     return actionCollection()->actions();
00512 }
00513 
00514 KexiDialogBase* KexiMainWindowImpl::currentDialog() const
00515 {
00516     return d->curDialog;
00517 }
00518 
00519 void KexiMainWindowImpl::initActions()
00520 {
00521 //  setupGUI(KMainWindow::Keys|KMainWindow::StatusBar|KMainWindow::Save|KMainWindow::Create);
00522 
00523 //  d->actionMapper = new QSignalMapper(this, "act_map");
00524 //  connect(d->actionMapper, SIGNAL(mapped(const QString &)), this, SLOT(slotAction(const QString &)));
00525 
00526     // PROJECT MENU
00527     KAction *action = new KAction(i18n("&New..."), "filenew", KStdAccel::shortcut(KStdAccel::New),
00528         this, SLOT(slotProjectNew()), actionCollection(), "project_new");
00529     action->setToolTip(i18n("Create a new project"));
00530     action->setWhatsThis(i18n("Creates a new project. Currently opened project is not affected."));
00531 
00532     action = KStdAction::open( this, SLOT( slotProjectOpen() ), actionCollection(), "project_open" );
00533     action->setToolTip(i18n("Open an existing project"));
00534     action->setWhatsThis(i18n("Opens an existing project. Currently opened project is not affected."));
00535 
00536 #ifdef HAVE_KNEWSTUFF
00537     action = new KAction(i18n("&Download Example Databases..."), "kget", KShortcut(0),
00538         this, SLOT(slotGetNewStuff()), actionCollection(), "project_download_examples");
00539     action->setToolTip(i18n("Download example databases from the Internet"));
00540     action->setWhatsThis(i18n("Downloads example databases from the Internet."));
00541 #endif
00542 
00543 //  d->action_open_recent = KStdAction::openRecent( this, SLOT(slotProjectOpenRecent(const KURL&)), actionCollection(), "project_open_recent" );
00544 
00545 //#ifdef KEXI_SHOW_UNIMPLEMENTED
00546 #ifndef KEXI_NO_UNFINISHED
00547     d->action_open_recent = new KActionMenu(i18n("Open Recent"),
00548         actionCollection(), "project_open_recent");
00549     connect(d->action_open_recent->popupMenu(),SIGNAL(activated(int)),
00550         this,SLOT(slotProjectOpenRecent(int)));
00551     connect(d->action_open_recent->popupMenu(), SIGNAL(aboutToShow()),
00552         this,SLOT(slotProjectOpenRecentAboutToShow()));
00553 //moved down        d->action_open_recent_projects_title_id = 
00554 //      d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Opened Databases"));
00555 //moved down    d->action_open_recent_connections_title_id = 
00556 //      d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Connected Database Servers"));
00557 //  d->action_open_recent->popupMenu()->insertSeparator();
00558 //  d->action_open_recent_more_id = d->action_open_recent->popupMenu()
00559 //      ->insertItem(i18n("&More Projects..."), this, SLOT(slotProjectOpenRecentMore()), 0, 1000);
00560 #else
00561     d->action_open_recent = d->dummy_action;
00562 #endif
00563 
00564     d->action_save = KStdAction::save( 
00565         this, SLOT( slotProjectSave() ), actionCollection(), "project_save" );
00566 //  d->action_save = new KAction(i18n("&Save"), "filesave", KStdAccel::shortcut(KStdAccel::Save),
00567 //      this, SLOT(slotProjectSave()), actionCollection(), "project_save");
00568     d->action_save->setToolTip(i18n("Save object changes"));
00569     d->action_save->setWhatsThis(i18n("Saves object changes from currently selected window."));
00570 
00571 #ifdef KEXI_SHOW_UNIMPLEMENTED
00572     d->action_save_as = new KAction(i18n("Save &As..."), "filesaveas", 0,
00573         this, SLOT(slotProjectSaveAs()), actionCollection(), "project_saveas");
00574     d->action_save_as->setToolTip(i18n("Save object as"));
00575     d->action_save_as->setWhatsThis(
00576         i18n("Saves object changes from currently selected window under a new name (within the same project)."));
00577 
00578     d->action_project_properties = new KAction(i18n("Project Properties"), "info", 0,
00579         this, SLOT(slotProjectProperties()), actionCollection(), "project_properties");
00580 #else
00581     d->action_save_as = d->dummy_action;
00582     d->action_project_properties = d->dummy_action;
00583 #endif
00584 
00585     d->action_close = new KAction(i18n("&Close Project"), "fileclose", 0,
00586         this, SLOT(slotProjectClose()), actionCollection(), "project_close" );
00587     d->action_close->setToolTip(i18n("Close the current project"));
00588     d->action_close->setWhatsThis(i18n("Closes the current project."));
00589 
00590     KStdAction::quit( this, SLOT(slotProjectQuit()), actionCollection(), "quit");
00591 
00592 #ifdef KEXI_SHOW_UNIMPLEMENTED
00593     d->action_project_relations = new KAction(i18n("&Relationships..."), "relation", Qt::CTRL + Qt::Key_R,
00594         this, SLOT(slotProjectRelations()), actionCollection(), "project_relations");
00595     d->action_project_relations->setToolTip(i18n("Project relationships"));
00596     d->action_project_relations->setWhatsThis(i18n("Shows project relationships."));
00597 
00598 #else
00599     d->action_project_relations = d->dummy_action;
00600 #endif
00601     d->action_tools_data_migration = new KAction(
00602         i18n("&Import Database..."), "database_import", 0,
00603         this, SLOT(slotToolsProjectMigration()), actionCollection(), "tools_import_project");
00604     d->action_tools_data_migration->setToolTip(i18n("Import entire database as a Kexi project"));
00605     d->action_tools_data_migration->setWhatsThis(i18n("Imports entire database as a Kexi project."));
00606 
00607     d->action_tools_compact_database = new KAction(
00608         i18n("&Compact Database..."), "", 0,
00609         this, SLOT(slotToolsCompactDatabase()), actionCollection(), "tools_compact_database");
00610     d->action_tools_compact_database->setToolTip(i18n("Compact the current database project"));
00611     d->action_tools_compact_database->setWhatsThis(
00612         i18n("Compacts the current database project, so it will take less space and work faster."));
00613 
00614     if (userMode())
00615         d->action_project_import_data_table = 0;
00616     else {
00617         d->action_project_import_data_table = new KAction(
00618             i18n("Import->Table Data From File...", "Table Data From &File..."),
00619             "table",
00620             0, this, SLOT(slotProjectImportDataTable()), actionCollection(), 
00621             "project_import_data_table");
00622         d->action_project_import_data_table->setToolTip(i18n("Import table data from a file"));
00623         d->action_project_import_data_table->setWhatsThis(i18n("Imports table data from a file."));
00624     }
00625 
00626     d->action_project_export_data_table = new KAction(i18n("Export->Table or Query Data to File...", 
00627         "Table or Query Data to &File..."),
00628         "table",
00629         0, this, SLOT(slotProjectExportDataTable()), actionCollection(), 
00630         "project_export_data_table");
00631     d->action_project_export_data_table->setToolTip(
00632         i18n("Export data from the active table or query data to a file"));
00633     d->action_project_export_data_table->setWhatsThis(
00634         i18n("Exports data from the active table or query data to a file."));
00635 
00636 //TODO  new KAction(i18n("From File..."), "fileopen", 0,
00637 //TODO      this, SLOT(slotImportFile()), actionCollection(), "project_import_file");
00638 //TODO  new KAction(i18n("From Server..."), "server", 0,
00639 //TODO      this, SLOT(slotImportServer()), actionCollection(), "project_import_server");
00640 
00641     d->action_project_print = KStdAction::print(this, SLOT(slotProjectPrint()),
00642         actionCollection(), "project_print" ); 
00643     d->action_project_print->setToolTip(i18n("Print data from the active table or query"));
00644     d->action_project_print->setWhatsThis(i18n("Prints data from the active table or query."));
00645 
00646     d->action_project_print_preview = KStdAction::printPreview(
00647         this, SLOT(slotProjectPrintPreview()),
00648         actionCollection(), "project_print_preview" ); 
00649     d->action_project_print_preview->setToolTip(
00650         i18n("Show print preview for the active table or query"));
00651     d->action_project_print_preview->setWhatsThis(
00652         i18n("Shows print preview for the active table or query."));
00653 
00654     d->action_project_print_setup = new KAction(i18n("Page Set&up..."),
00655         "", 0, this, SLOT(slotProjectPageSetup()), actionCollection(), 
00656         "project_print_setup");
00657     d->action_project_print_setup->setToolTip(
00658         i18n("Show page setup for printing the active table or query"));
00659     d->action_project_print_setup->setWhatsThis(
00660         i18n("Shows page setup for printing the active table or query."));
00661 
00662     //EDIT MENU
00663     d->action_edit_cut = createSharedAction( KStdAction::Cut, "edit_cut");
00664     d->action_edit_copy = createSharedAction( KStdAction::Copy, "edit_copy");
00665     d->action_edit_paste = createSharedAction( KStdAction::Paste, "edit_paste");
00666 
00667     if (userMode())
00668         d->action_edit_paste_special_data_table = 0;
00669     else {
00670         d->action_edit_paste_special_data_table = 
00671             new KAction(i18n("Paste Special->As Data &Table...", "As Data &Table..."),
00672             "table", 0, this, SLOT(slotEditPasteSpecialDataTable()),
00673             actionCollection(), "edit_paste_special_data_table");
00674         d->action_edit_paste_special_data_table->setToolTip(
00675             i18n("Paste clipboard data as a table"));
00676         d->action_edit_paste_special_data_table->setWhatsThis(
00677             i18n("Pastes clipboard data to a table."));
00678     }
00679 
00680     d->action_edit_copy_special_data_table =
00681         new KAction(i18n("Copy Special->Table or Query Data...", 
00682             "Table or Query as Data Table..."),
00683         "table", 0, this, SLOT(slotEditCopySpecialDataTable()),
00684         actionCollection(), "edit_copy_special_data_table");
00685     d->action_edit_copy_special_data_table->setToolTip(
00686         i18n("Copy selected table or query data to clipboard"));
00687     d->action_edit_copy_special_data_table->setWhatsThis(
00688         i18n("Copies selected table or query data to clipboard."));
00689 
00690     d->action_edit_undo = createSharedAction( KStdAction::Undo, "edit_undo");
00691     d->action_edit_undo->setWhatsThis(i18n("Reverts the most recent editing action."));
00692     d->action_edit_redo = createSharedAction( KStdAction::Redo, "edit_redo");
00693     d->action_edit_redo->setWhatsThis(i18n("Reverts the most recent undo action."));
00694 
00695 #if 0 //old
00696     d->action_edit_find = createSharedAction( KStdAction::Find, "edit_find");
00697     d->action_edit_findnext = createSharedAction( KStdAction::FindNext, "edit_findnext");
00698     d->action_edit_findprev = createSharedAction( KStdAction::FindPrev, "edit_findprevious");
00700 #endif
00701 
00702     d->action_edit_find = KStdAction::find(
00703         this, SLOT(slotEditFind()), actionCollection(), "edit_find" );
00704 //  d->action_edit_find = createSharedAction( KStdAction::Find, "edit_find");
00705     d->action_edit_findnext = KStdAction::findNext(
00706         this, SLOT(slotEditFindNext()), actionCollection(), "edit_findnext");
00707     d->action_edit_findprev = KStdAction::findPrev(
00708         this, SLOT(slotEditFindPrevious()), actionCollection(), "edit_findprevious");
00709     d->action_edit_replace = 0;
00712     d->action_edit_replace_all = 0;
00715 
00716     d->action_edit_select_all =  createSharedAction( KStdAction::SelectAll, "edit_select_all");
00717 
00718     d->action_edit_delete = createSharedAction(i18n("&Delete"), "editdelete",
00719         0/*Qt::Key_Delete*/, "edit_delete");
00720     d->action_edit_delete->setToolTip(i18n("Delete selected object"));
00721     d->action_edit_delete->setWhatsThis(i18n("Deletes currently selected object."));
00722 
00723     d->action_edit_delete_row = createSharedAction(i18n("Delete Row"), "delete_table_row",
00724         Qt::CTRL+Qt::Key_Delete, "edit_delete_row");
00725     d->action_edit_delete_row->setToolTip(i18n("Delete currently selected row"));
00726     d->action_edit_delete_row->setWhatsThis(i18n("Deletes currently selected row."));
00727 
00728     d->action_edit_clear_table = createSharedAction(i18n("Clear Table Contents"), "clear_table_contents",
00729         0, "edit_clear_table");
00730     d->action_edit_clear_table->setToolTip(i18n("Clear table contents"));
00731     d->action_edit_clear_table->setWhatsThis(i18n("Clears table contents."));
00732     setActionVolatile( d->action_edit_clear_table, true );
00733 
00734     d->action_edit_edititem = createSharedAction(i18n("Edit Item"), 0, 0, /* CONFLICT in TV: Qt::Key_F2,  */
00735         "edit_edititem");
00736     d->action_edit_edititem->setToolTip(i18n("Edit currently selected item"));
00737     d->action_edit_edititem->setWhatsThis(i18n("Edits currently selected item."));
00738 
00739     d->action_edit_insert_empty_row = createSharedAction(i18n("&Insert Empty Row"), "insert_table_row", 
00740         Qt::SHIFT | Qt::CTRL | Qt::Key_Insert, "edit_insert_empty_row");
00741     setActionVolatile( d->action_edit_insert_empty_row, true );
00742     d->action_edit_insert_empty_row->setToolTip(i18n("Insert one empty row above"));
00743     d->action_edit_insert_empty_row->setWhatsThis(i18n("Inserts one empty row above currently selected table row."));
00744 
00745     //VIEW MENU
00746     if (!userMode()) {
00747         d->action_view_data_mode = new KRadioAction(i18n("&Data View"), "state_data", Qt::Key_F6,
00748             this, SLOT(slotViewDataMode()), actionCollection(), "view_data_mode");
00749         d->actions_for_view_modes.insert( Kexi::DataViewMode, d->action_view_data_mode );
00750         d->action_view_data_mode->setExclusiveGroup("view_mode");
00751         d->action_view_data_mode->setToolTip(i18n("Switch to data view"));
00752         d->action_view_data_mode->setWhatsThis(i18n("Switches to data view."));
00753     }
00754     else
00755         d->action_view_data_mode = 0;
00756 
00757     if (!userMode()) {
00758         d->action_view_design_mode = new KRadioAction(i18n("D&esign View"), "state_edit", Qt::Key_F7,
00759             this, SLOT(slotViewDesignMode()), actionCollection(), "view_design_mode");
00760         d->actions_for_view_modes.insert( Kexi::DesignViewMode, d->action_view_design_mode );
00761         d->action_view_design_mode->setExclusiveGroup("view_mode");
00762         d->action_view_design_mode->setToolTip(i18n("Switch to design view"));
00763         d->action_view_design_mode->setWhatsThis(i18n("Switches to design view."));
00764     }
00765     else
00766         d->action_view_design_mode = 0;
00767 
00768     if (!userMode()) {
00769         d->action_view_text_mode = new KRadioAction(i18n("&Text View"), "state_sql", Qt::Key_F8,
00770             this, SLOT(slotViewTextMode()), actionCollection(), "view_text_mode");
00771         d->actions_for_view_modes.insert( Kexi::TextViewMode, d->action_view_text_mode );
00772         d->action_view_text_mode->setExclusiveGroup("view_mode");
00773         d->action_view_text_mode->setToolTip(i18n("Switch to text view"));
00774         d->action_view_text_mode->setWhatsThis(i18n("Switches to text view."));
00775     }
00776     else
00777         d->action_view_text_mode = 0;
00778 
00779     if (d->isProjectNavigatorVisible) {
00780         d->action_view_nav = new KAction(i18n("Project Navigator"), "", Qt::ALT + Qt::Key_1,
00781             this, SLOT(slotViewNavigator()), actionCollection(), "view_navigator");
00782         d->action_view_nav->setToolTip(i18n("Go to project navigator panel"));
00783         d->action_view_nav->setWhatsThis(i18n("Goes to project navigator panel."));
00784     }
00785     else
00786         d->action_view_nav = 0;
00787 
00788     d->action_view_mainarea = new KAction(i18n("Main Area"), "", Qt::ALT + Qt::Key_2,
00789         this, SLOT(slotViewMainArea()), actionCollection(), "view_mainarea");
00790     d->action_view_mainarea->setToolTip(i18n("Go to main area"));
00791     d->action_view_mainarea->setWhatsThis(i18n("Goes to main area."));
00792 
00793     if (!userMode()) {
00794         d->action_view_propeditor = new KAction(i18n("Property Editor"), "", Qt::ALT + Qt::Key_3,
00795             this, SLOT(slotViewPropertyEditor()), actionCollection(), "view_propeditor");
00796         d->action_view_propeditor->setToolTip(i18n("Go to property editor panel"));
00797         d->action_view_propeditor->setWhatsThis(i18n("Goes to property editor panel."));
00798     }
00799     else
00800         d->action_view_propeditor = 0;
00801 
00802     //DATA MENU
00803     d->action_data_save_row = createSharedAction(i18n("&Save Row"), "button_ok", 
00804         Qt::SHIFT | Qt::Key_Return, "data_save_row");
00805     d->action_data_save_row->setToolTip(i18n("Save changes made to the current row"));
00806     d->action_data_save_row->setWhatsThis(i18n("Saves changes made to the current row."));
00807 //temp. disable because of problems with volatile actions   setActionVolatile( d->action_data_save_row, true );
00808 
00809     d->action_data_cancel_row_changes = createSharedAction(i18n("&Cancel Row Changes"), 
00810         "button_cancel", 0 , "data_cancel_row_changes");
00811     d->action_data_cancel_row_changes->setToolTip(i18n("Cancel changes made to the current row"));
00812     d->action_data_cancel_row_changes->setWhatsThis(i18n("Cancels changes made to the current row."));
00813 //temp. disable because of problems with volatile actions   setActionVolatile( d->action_data_cancel_row_changes, true );
00814 
00815     d->action_data_execute = createSharedAction(i18n("&Execute"), "player_play", 0 , "data_execute");
00816     //d->action_data_execute->setToolTip(i18n("")); //TODO
00817     //d->action_data_execute->setWhatsThis(i18n("")); //TODO
00818 
00819 #ifndef KEXI_NO_UNFINISHED
00820     action = createSharedAction(i18n("&Filter"), "filter", 0, "data_filter");
00821     setActionVolatile( action, true );
00822 #endif
00823 //  action->setToolTip(i18n("")); //todo
00824 //  action->setWhatsThis(i18n("")); //todo
00825 
00826 //  setSharedMenu("data_sort");
00827     action = createSharedAction(i18n("&Ascending"), "sort_az", 0, "data_sort_az");
00828 //temp. disable because of problems with volatile actions   setActionVolatile( action, true );
00829     action->setToolTip(i18n("Sort data in ascending order"));
00830     action->setWhatsThis(i18n("Sorts data in ascending order (from A to Z and from 0 to 9). Data from selected column is used for sorting."));
00831 
00832     action = createSharedAction(i18n("&Descending"), "sort_za", 0, "data_sort_za");
00833 //temp. disable because of problems with volatile actions   setActionVolatile( action, true );
00834     action->setToolTip(i18n("Sort data in descending order"));
00835     action->setWhatsThis(i18n("Sorts data in descending (from Z to A and from 9 to 0). Data from selected column is used for sorting."));
00836 
00837     // - record-navigation related actions
00838     createSharedAction( KexiRecordNavigator::Actions::moveToFirstRecord(), 0, "data_go_to_first_record");
00839     createSharedAction( KexiRecordNavigator::Actions::moveToPreviousRecord(), 0, "data_go_to_previous_record");
00840     createSharedAction( KexiRecordNavigator::Actions::moveToNextRecord(), 0, "data_go_to_next_record");
00841     createSharedAction( KexiRecordNavigator::Actions::moveToLastRecord(), 0, "data_go_to_last_record");
00842     createSharedAction( KexiRecordNavigator::Actions::moveToNewRecord(), 0, "data_go_to_new_record");
00843 
00844     //FORMAT MENU
00845     d->action_format_font = createSharedAction(i18n("&Font..."), "fonts", 0, "format_font");
00846     d->action_format_font->setToolTip(i18n("Change font for selected object"));
00847     d->action_format_font->setWhatsThis(i18n("Changes font for selected object."));
00848 
00849     //TOOLS MENU
00850 
00851     //WINDOW MENU
00852 #ifndef Q_WS_WIN
00853     //KMDI <= 3.5.1 has no shortcut here:
00854     KAction *closeWindowAction = actionCollection()->action("window_close");
00855     if (closeWindowAction)
00856         closeWindowAction->setShortcut(KStdAccel::close());
00857 #endif
00858 
00859     //additional 'Window' menu items
00860     d->action_window_next = new KAction( i18n("&Next Window"), "",
00861 #ifdef Q_WS_WIN
00862         Qt::CTRL+Qt::Key_Tab,
00863 #else
00864         Qt::ALT+Qt::Key_Right,
00865 #endif
00866         this, SLOT(activateNextWin()), actionCollection(), "window_next");
00867     d->action_window_next->setToolTip( i18n("Next window") );
00868     d->action_window_next->setWhatsThis(i18n("Switches to the next window."));
00869 
00870     d->action_window_previous = new KAction( i18n("&Previous Window"), "",
00871 #ifdef Q_WS_WIN
00872         Qt::CTRL+Qt::SHIFT+Qt::Key_Tab,
00873 #else
00874         Qt::ALT+Qt::Key_Left,
00875 #endif
00876         this, SLOT(activatePrevWin()), actionCollection(), "window_previous");
00877     d->action_window_previous->setToolTip( i18n("Previous window") );
00878     d->action_window_previous->setWhatsThis(i18n("Switches to the previous window."));
00879 
00880     //SETTINGS MENU
00881     setStandardToolBarMenuEnabled( true );
00882     action = KStdAction::keyBindings(this, SLOT( slotConfigureKeys() ), actionCollection() );
00883     action->setWhatsThis(i18n("Lets you configure shortcut keys."));
00884 
00885 #ifdef KEXI_SHOW_UNIMPLEMENTED
00886     action = KStdAction::configureToolbars( this, SLOT( slotConfigureToolbars() ), actionCollection() );
00887     action->setWhatsThis(i18n("Lets you configure toolbars."));
00888 
00889     d->action_show_other = new KActionMenu(i18n("Other"),
00890         actionCollection(), "options_show_other");
00891 #endif
00892 
00893 #ifndef KEXI_NO_CTXT_HELP
00894     d->action_show_helper = new KToggleAction(i18n("Show Context Help"), "", Qt::CTRL + Qt::Key_H,
00895      actionCollection(), "options_show_contexthelp");
00896 #if KDE_IS_VERSION(3,2,90)
00897     d->action_show_helper->setCheckedState(i18n("Hide Context Help"));
00898 #endif
00899 #endif
00900 
00901 #ifdef KEXI_FORMS_SUPPORT
00902     slotOptionsEnableForms(true, true);
00903 #else
00904     slotOptionsEnableForms(false, true);
00905 #endif
00906 
00907 #ifdef KEXI_REPORTS_SUPPORT
00908     Kexi::tempShowReports() = true;
00909 #else
00910     Kexi::tempShowReports() = false;
00911 #endif
00912 
00913 #ifdef KEXI_MACROS_SUPPORT
00914     Kexi::tempShowMacros() = true;
00915 #else
00916     Kexi::tempShowMacros() = false;
00917 #endif
00918 
00919 #ifdef KEXI_SCRIPTS_SUPPORT
00920     Kexi::tempShowScripts() = true;
00921 #else
00922     Kexi::tempShowScripts() = false;
00923 #endif
00924 
00925 #ifdef KEXI_SHOW_UNIMPLEMENTED
00926     d->action_configure = KStdAction::preferences(this, SLOT(slotShowSettings()), actionCollection());
00927     action->setWhatsThis(i18n("Lets you configure Kexi."));
00928 #endif
00929 
00930     //HELP MENU
00931 #if 0//js: todo reenable later
00932     KStdAction::tipOfDay( this, SLOT( slotTipOfTheDayAction() ), actionCollection() )
00933         ->setWhatsThis(i18n("This shows useful tips on the use of this application."));
00934 #endif
00935 #if 0 //we don't have a time for updating info text for each new version
00936     new KAction(i18n("Important Information"), "messagebox_info", 0,
00937         this, SLOT(slotImportantInfo()), actionCollection(), "help_show_important_info");
00938 #endif
00939 //TODO: UNCOMMENT TO REMOVE MDI MODES SETTING   m_pMdiModeMenu->hide();
00940 
00941 #ifndef KEXI_NO_FEEDBACK_AGENT
00942 #ifdef FEEDBACK_CLASS
00943     new KAction(i18n("Give Feedback..."), "messagebox_info", 0,
00944         this, SLOT(slotStartFeedbackAgent()), actionCollection(), "help_start_feedback_agent");
00945 #endif
00946 #endif
00947 //  KAction *actionSettings = new KAction(i18n("Configure Kexi..."), "configure", 0,
00948 //   actionCollection(), "kexi_settings");
00949 //  actionSettings->setWhatsThis(i18n("Lets you configure Kexi."));
00950 //  connect(actionSettings, SIGNAL(activated()), this, SLOT(slotShowSettings()));
00951 
00952     // -- add a few missing tooltips (usable especially in Form's "Assign action" dialog)
00953     if ((action = actionCollection()->action("window_close")))
00954         action->setToolTip(i18n("Close the current window"));
00955 
00956     // ----- declare action categories, so form's "assign action to button"
00957     //       (and macros in the future) will be able to recognize category 
00958     //       of actions and filter them -----------------------------------
00960     Kexi::ActionCategories *acat = Kexi::actionCategories();
00961     acat->addAction("data_execute", Kexi::PartItemActionCategory);
00962 
00964     acat->addWindowAction("data_filter",
00965         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
00966 
00967     acat->addWindowAction("data_save_row",
00968         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
00969 
00970     acat->addWindowAction("data_cancel_row_changes",
00971         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
00972 
00973     acat->addWindowAction("delete_table_row",
00974         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
00975 
00977     acat->addWindowAction("data_sort_az",
00978         KexiPart::TableObjectType, KexiPart::QueryObjectType);
00979 
00981     acat->addWindowAction("data_sort_za",
00982         KexiPart::TableObjectType, KexiPart::QueryObjectType);
00983 
00985     acat->addWindowAction("edit_clear_table",
00986         KexiPart::TableObjectType, KexiPart::QueryObjectType);
00987 
00989     acat->addWindowAction("edit_copy_special_data_table", 
00990         KexiPart::TableObjectType, KexiPart::QueryObjectType);
00991 
00992     // GlobalActions, etc.
00993     acat->addAction("edit_copy", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
00994 
00995     acat->addAction("edit_cut", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
00996 
00997     acat->addAction("edit_paste", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
00998 
00999     acat->addAction("edit_delete", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory|Kexi::WindowActionCategory,
01000         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01001 
01002     acat->addAction("edit_delete_row", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01003         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01004 
01005     acat->addAction("edit_edititem", Kexi::PartItemActionCategory|Kexi::WindowActionCategory,
01006         KexiPart::TableObjectType, KexiPart::QueryObjectType);
01007 
01008     acat->addAction("edit_find", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01009         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01010 
01011     acat->addAction("edit_findnext", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01012         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01013 
01014     acat->addAction("edit_findprevious", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01015         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01016 
01017     acat->addAction("edit_replace", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01018         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01019 
01020     acat->addAction("edit_paste_special_data_table", Kexi::GlobalActionCategory);
01021 
01022     acat->addAction("help_about_app", Kexi::GlobalActionCategory);
01023 
01024     acat->addAction("help_about_kde", Kexi::GlobalActionCategory);
01025 
01026     acat->addAction("help_contents", Kexi::GlobalActionCategory);
01027 
01028     acat->addAction("help_report_bug", Kexi::GlobalActionCategory);
01029 
01030     acat->addAction("help_whats_this", Kexi::GlobalActionCategory);
01031 
01032     acat->addAction("options_configure_keybinding", Kexi::GlobalActionCategory);
01033 
01034     acat->addAction("project_close", Kexi::GlobalActionCategory);
01035 
01037     acat->addAction("project_export_data_table", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
01038         KexiPart::TableObjectType, KexiPart::QueryObjectType);
01039 
01040     acat->addAction("project_import_data_table", Kexi::GlobalActionCategory);
01041 
01042     acat->addAction("project_new", Kexi::GlobalActionCategory);
01043 
01044     acat->addAction("project_open", Kexi::GlobalActionCategory);
01045 
01047     acat->addAction("project_print", Kexi::WindowActionCategory,
01048         KexiPart::TableObjectType, KexiPart::QueryObjectType);
01049 
01051     acat->addAction("project_print_preview", Kexi::WindowActionCategory,
01052         KexiPart::TableObjectType, KexiPart::QueryObjectType);
01053 
01055     acat->addAction("project_print_setup", Kexi::WindowActionCategory,
01056         KexiPart::TableObjectType, KexiPart::QueryObjectType);
01057 
01058     acat->addAction("quit", Kexi::GlobalActionCategory);
01059 
01060     acat->addAction("tools_compact_database", Kexi::GlobalActionCategory);
01061 
01062     acat->addAction("tools_import_project", Kexi::GlobalActionCategory);
01063 
01064     acat->addAction("view_data_mode", Kexi::GlobalActionCategory);
01065 
01066     acat->addAction("view_design_mode", Kexi::GlobalActionCategory);
01067 
01068     acat->addAction("view_text_mode", Kexi::GlobalActionCategory);
01069 
01070     acat->addAction("view_mainarea", Kexi::GlobalActionCategory);
01071 
01072     acat->addAction("view_navigator", Kexi::GlobalActionCategory);
01073 
01074     acat->addAction("view_propeditor", Kexi::GlobalActionCategory);
01075 
01076     acat->addAction("window_close", Kexi::GlobalActionCategory | Kexi::WindowActionCategory);
01077     acat->setAllObjectTypesSupported("window_close", true);
01078 
01079     acat->addAction("window_next", Kexi::GlobalActionCategory);
01080 
01081     acat->addAction("window_previous", Kexi::GlobalActionCategory);
01082 
01083     //skipped - design view only
01084     acat->addAction("format_font", Kexi::NoActionCategory);
01085     acat->addAction("project_save", Kexi::NoActionCategory);
01086     acat->addAction("edit_insert_empty_row", Kexi::NoActionCategory);
01088     acat->addAction("edit_select_all", Kexi::NoActionCategory);
01090     acat->addAction("edit_redo", Kexi::NoActionCategory);
01092     acat->addAction("edit_undo", Kexi::NoActionCategory);
01093 
01094     //record-navigation related actions
01095     acat->addAction("data_go_to_first_record", Kexi::WindowActionCategory,
01096         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01097     acat->addAction("data_go_to_previous_record", Kexi::WindowActionCategory,
01098         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01099     acat->addAction("data_go_to_next_record", Kexi::WindowActionCategory,
01100         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01101     acat->addAction("data_go_to_last_record", Kexi::WindowActionCategory,
01102         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01103     acat->addAction("data_go_to_new_record", Kexi::WindowActionCategory,
01104         KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
01105 
01106     //skipped - internal: 
01107     acat->addAction("tablepart_create", Kexi::NoActionCategory);
01108     acat->addAction("querypart_create", Kexi::NoActionCategory);
01109     acat->addAction("formpart_create", Kexi::NoActionCategory);
01110     acat->addAction("reportpart_create", Kexi::NoActionCategory);
01111     acat->addAction("macropart_create", Kexi::NoActionCategory);
01112     acat->addAction("scriptpart_create", Kexi::NoActionCategory);
01113 }
01114 
01115 void KexiMainWindowImpl::invalidateActions()
01116 {
01117     invalidateProjectWideActions();
01118     invalidateSharedActions();
01119 }
01120 
01121 void KexiMainWindowImpl::invalidateSharedActions(QObject *o)
01122 {
01123     //TODO: enabling is more complex...
01124 /*  d->action_edit_cut->setEnabled(true);
01125     d->action_edit_copy->setEnabled(true);
01126     d->action_edit_paste->setEnabled(true);*/
01127 
01128     if (!o)
01129         o = focusWindow();
01130     KexiSharedActionHost::invalidateSharedActions(o);
01131 }
01132 
01133 void KexiMainWindowImpl::invalidateSharedActions()
01134 {
01135     invalidateSharedActions(0);
01136 }
01137 
01138 // unused, I think
01139 void KexiMainWindowImpl::invalidateSharedActionsLater()
01140 {
01141     QTimer::singleShot(1, this, SLOT(invalidateSharedActions()));
01142 }
01143 
01144 void KexiMainWindowImpl::invalidateProjectWideActions()
01145 {
01146 //  stateChanged("project_opened",d->prj ? StateNoReverse : StateReverse);
01147 
01148     const bool have_dialog = d->curDialog;
01149     const bool dialog_dirty = d->curDialog && d->curDialog->dirty();
01150     const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->isReadOnly();
01151 
01152     //PROJECT MENU
01153     d->action_save->setEnabled(have_dialog && dialog_dirty && !readOnly);
01154     d->action_save_as->setEnabled(have_dialog && !readOnly);
01155     d->action_project_properties->setEnabled(d->prj);
01156     d->action_close->setEnabled(d->prj);
01157     d->action_project_relations->setEnabled(d->prj);
01158     if (d->action_project_import_data_table)
01159         d->action_project_import_data_table->setEnabled(d->prj && !readOnly);
01160     d->action_project_export_data_table->setEnabled( 
01161         d->curDialog && d->curDialog->part()->info()->isDataExportSupported() 
01162         && !d->curDialog->neverSaved() );
01163 
01164     const bool printingActionsEnabled = 
01165         d->curDialog && d->curDialog->part()->info()->isPrintingSupported()
01166         && !d->curDialog->neverSaved();
01167     d->action_project_print->setEnabled( printingActionsEnabled );
01168     d->action_project_print_preview->setEnabled( printingActionsEnabled );
01169     d->action_project_print_setup->setEnabled( printingActionsEnabled );
01170 
01171     //EDIT MENU
01172 
01173     if (d->action_edit_paste_special_data_table)
01174         d->action_edit_paste_special_data_table->setEnabled(d->prj && !readOnly);
01175 
01178     if (d->curDialog && d->curDialog->currentViewMode()==Kexi::DataViewMode) {
01179         KexiPart::Info *activePartInfo = d->curDialog->part()->info();
01180         d->action_edit_copy_special_data_table->setEnabled(
01181             activePartInfo ? activePartInfo->isDataExportSupported() : false );
01182     }
01183     else
01184         d->action_edit_copy_special_data_table->setEnabled( false );
01185 
01186     //VIEW MENU
01187     if (d->action_view_nav)
01188         d->action_view_nav->setEnabled(d->prj);
01189     d->action_view_mainarea->setEnabled(d->prj);
01190     if (d->action_view_propeditor)
01191         d->action_view_propeditor->setEnabled(d->prj);
01192     if (d->action_view_data_mode) {
01193         d->action_view_data_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::DataViewMode) );
01194         if (!d->action_view_data_mode->isEnabled())
01195             d->action_view_data_mode->setChecked(false);
01196     }
01197     if (d->action_view_design_mode) {
01198         d->action_view_design_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::DesignViewMode) );
01199         if (!d->action_view_design_mode->isEnabled())
01200             d->action_view_design_mode->setChecked(false);
01201     }
01202     if (d->action_view_text_mode) {
01203         d->action_view_text_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::TextViewMode) );
01204         if (!d->action_view_text_mode->isEnabled())
01205             d->action_view_text_mode->setChecked(false);
01206     }
01207 #ifndef KEXI_NO_CTXT_HELP
01208     d->action_show_helper->setEnabled(d->prj);
01209 #endif
01210 
01211     //CREATE MENU
01212     if (d->createMenu)
01213         d->createMenu->setEnabled(d->prj);
01214 
01215     // DATA MENU
01216     //d->action_data_execute->setEnabled( d->curDialog && d->curDialog->part()->info()->isExecuteSupported() );
01217 
01218     //TOOLS MENU
01219     // "compact db" supported if there's no db or the current db supports compacting and is opened r/w:
01220     d->action_tools_compact_database->setEnabled( 
01221         !d->prj || !readOnly && d->prj && d->prj->dbConnection() 
01222         && (d->prj->dbConnection()->driver()->features() & KexiDB::Driver::CompactingDatabaseSupported) );
01223 
01224     //WINDOW MENU
01225     if (d->action_window_next) {
01226         d->action_window_next->setEnabled(!m_pDocumentViews->isEmpty());
01227         d->action_window_previous->setEnabled(!m_pDocumentViews->isEmpty());
01228     }
01229 
01230     //DOCKS
01231     if (d->nav)
01232         d->nav->setEnabled(d->prj);
01233     if (d->propEditor)
01234         d->propEditorTabWidget->setEnabled(d->prj);
01235 }
01236 
01237 void KexiMainWindowImpl::invalidateViewModeActions()
01238 {
01239     if (d->curDialog) {
01240         //update toggle action
01241         if (d->curDialog->currentViewMode()==Kexi::DataViewMode) {
01242             if (d->action_view_data_mode)
01243                 d->action_view_data_mode->setChecked( true );
01244         }
01245         else if (d->curDialog->currentViewMode()==Kexi::DesignViewMode) {
01246             if (d->action_view_design_mode)
01247                 d->action_view_design_mode->setChecked( true );
01248         }
01249         else if (d->curDialog->currentViewMode()==Kexi::TextViewMode) {
01250             if (d->action_view_text_mode)
01251                 d->action_view_text_mode->setChecked( true );
01252         }
01253     }
01254 }
01255 
01256 tristate KexiMainWindowImpl::startup()
01257 {
01258     switch (Kexi::startupHandler().action()) {
01259     case KexiStartupHandler::CreateBlankProject:
01260         if (d->propEditor)
01261             makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
01262         return createBlankProject();
01263     case KexiStartupHandler::CreateFromTemplate:
01264         return createProjectFromTemplate(*Kexi::startupHandler().projectData());
01265     case KexiStartupHandler::OpenProject:
01266         return openProject(*Kexi::startupHandler().projectData());
01267     case KexiStartupHandler::ImportProject:
01268         return showProjectMigrationWizard(
01269             Kexi::startupHandler().importActionData().mimeType,
01270             Kexi::startupHandler().importActionData().fileName
01271         );
01272     default:;
01273         if (d->propEditor)
01274             makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
01275     }
01276     return true;
01277 }
01278 
01279 static QString internalReason(KexiDB::Object *obj)
01280 {
01281     const QString &s = obj->errorMsg();
01282     if (s.isEmpty())
01283         return s;
01284     return QString("<br>(%1) ").arg(i18n("reason:")+" <i>"+s+"</i>");
01285 }
01286 
01287 tristate KexiMainWindowImpl::openProject(const KexiProjectData& projectData)
01288 {
01289     KexiProjectData *newProjectData = new KexiProjectData(projectData);
01290 //  if (userMode()) {
01291         //TODO: maybe also auto allow to open objects...
01292 //      return initUserModeMode(newProjectData);
01293 //  }
01294     createKexiProject( newProjectData );
01295     if (!newProjectData->connectionData()->savePassword 
01296         && newProjectData->connectionData()->password.isEmpty()
01297         && newProjectData->connectionData()->fileName().isEmpty() 
01298     )
01299     {
01300         //ask for password
01301         KexiDBPasswordDialog pwdDlg(this, *newProjectData->connectionData(), 
01302             false );
01303         if (QDialog::Accepted!=pwdDlg.exec()) {
01304             delete d->prj;
01305             d->prj = 0;
01306             return cancelled;
01307         }
01308     }
01309     bool incompatibleWithKexi;
01310     tristate res = d->prj->open(incompatibleWithKexi);
01311     if (~res) {
01312         delete d->prj;
01313         d->prj = 0;
01314         return cancelled;
01315     }
01316     else if (!res) {
01317         delete d->prj;
01318         d->prj = 0;
01319         if (incompatibleWithKexi) {
01320             if (KMessageBox::Yes == KMessageBox::questionYesNo(this,
01321                 i18n("<qt>Database project %1 does not appear to have been created using Kexi.<br><br>"
01322                 "Do you want to import it as a new Kexi project?</qt>").arg(projectData.infoString()),
01323                 0, KGuiItem(i18n("Import Database", "&Import..."), "database_import"),
01324                 KStdGuiItem::quit()))
01325             {
01326                 const bool anotherProjectAlreadyOpened = d->prj;
01327                 tristate res = showProjectMigrationWizard("application/x-kexi-connectiondata", 
01328                     projectData.databaseName(), projectData.constConnectionData());
01329                 
01330                 if (!anotherProjectAlreadyOpened) //the project could have been opened within this instance
01331                     return res;
01332 
01333                 //always return cancelled because even if migration succeeded, new Kexi instance 
01334                 //will be started if user wanted to open the imported db
01335                 return cancelled;
01336             }
01337             return cancelled;
01338         }
01339         return false;
01340     }
01341     initNavigator();
01342     Kexi::recentProjects().addProjectData( newProjectData );
01343     updateReadOnlyState();
01344     invalidateActions();
01345 //  d->disableErrorMessages = true;
01346     enableMessages( false );
01347 
01348     QTimer::singleShot(1, this, SLOT(slotAutoOpenObjectsLater()));
01349     return true;
01350 }
01351 
01352 tristate KexiMainWindowImpl::createProjectFromTemplate(const KexiProjectData& projectData)
01353 {
01354     QStringList mimetypes;
01355     mimetypes.append( KexiDB::Driver::defaultFileBasedDriverMimeType() );
01356     QString fname;
01357     const QString startDir(":OpenExistingOrCreateNewProject"/*as in KexiNewProjectWizard*/);
01358     const QString caption( i18n("Select New Project's Location") );
01359     
01360     while (true) {
01361 #ifdef Q_WS_WIN
01363         QString recentDir = KGlobalSettings::documentPath();
01364         if (fname.isEmpty() && !projectData.constConnectionData()->dbFileName().isEmpty()) //propose filename from db template name
01365           fname = KFileDialog::getStartURL(startDir, recentDir).path() 
01366                 + '/' + projectData.constConnectionData()->dbFileName();
01367         fname = QFileDialog::getSaveFileName( 
01368             KFileDialog::getStartURL(fname.isEmpty() ? startDir : fname, recentDir).path(),
01369             KexiUtils::fileDialogFilterStrings(mimetypes, false),
01370             this, "CreateProjectFromTemplate", caption);
01371         if ( !fname.isEmpty() ) {
01372             //save last visited path
01373             KURL url;
01374             url.setPath( fname );
01375             if (url.isLocalFile())
01376                 KRecentDirs::add(startDir, url.directory());
01377         }
01378 #else
01379         Q_UNUSED(projectData);
01380         if (fname.isEmpty() &&
01381             !projectData.constConnectionData()->dbFileName().isEmpty())
01382         {
01383             //propose filename from db template name
01384           fname = projectData.constConnectionData()->dbFileName();
01385         }
01386         const bool specialDir = fname.isEmpty();
01387     kdDebug() << fname << "............." << endl;
01388         KFileDialog dlg( specialDir ? startDir : QString::null, 
01389             mimetypes.join(" "), this, "filedialog", true);
01390         if ( !specialDir )
01391             dlg.setSelection( fname ); // may also be a filename
01392         dlg.setOperationMode( KFileDialog::Saving );
01393         dlg.setCaption( caption );
01394         dlg.exec();
01395         fname = dlg.selectedFile();
01396         if (!fname.isEmpty())
01397             KRecentDocument::add(fname);
01398 //      fname = KFileDialog::getSaveFileName(fname.isEmpty() ? startDir : fname, 
01399     //      mimetypes.join(" "), this, caption);
01400 #endif
01401         if ( fname.isEmpty() )
01402             return cancelled;
01403         if (KexiStartupFileDialog::askForOverwriting(fname, this))
01404             break;
01405     }
01406 
01407     if (KexiUtils::CopySuccess != KexiUtils::copyFile(
01408         projectData.constConnectionData()->fileName(), fname ))
01409     {
01410         return false;
01411     }
01412 
01413     return openProject(fname, 0, QString::null, projectData.autoopenObjects/*copy*/);
01414 }
01415 
01416 void KexiMainWindowImpl::updateReadOnlyState()
01417 {
01418     const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->isReadOnly();
01419     d->statusBar->setReadOnlyFlag( readOnly );
01420     if (d->nav)
01421         d->nav->setReadOnly(readOnly);
01422     // update "insert ....." actions for every part
01423     KActionCollection *ac = actionCollection();
01424     for (KexiPart::PartInfoListIterator it(*Kexi::partManager().partInfoList()); it.current(); ++it) {
01425         KAction *a = ac->action( KexiPart::nameForCreateAction( *it.current() ) );
01426         if (a)
01427             a->setEnabled(!readOnly);
01428     }
01429 }
01430 
01431 void KexiMainWindowImpl::slotAutoOpenObjectsLater()
01432 {
01433     QString not_found_msg;
01434     bool openingCancelled;
01435     //ok, now open "autoopen: objects
01436     if (d->prj) {
01437         for (QValueList<KexiProjectData::ObjectInfo>::ConstIterator it = 
01438                 d->prj->data()->autoopenObjects.constBegin();
01439             it != d->prj->data()->autoopenObjects.constEnd(); ++it )
01440         {
01441             KexiProjectData::ObjectInfo info = *it;
01442             KexiPart::Info *i = Kexi::partManager().infoForMimeType( 
01443                 QCString("kexi/")+info["type"].lower().latin1() );
01444             if (!i) {
01445                 not_found_msg += "<li>";
01446                 if (!info["name"].isEmpty())
01447                     not_found_msg += (QString("\"") + info["name"] + "\" - ");
01448                 if (info["action"]=="new")
01449                     not_found_msg += i18n("cannot create object - unknown object type \"%1\"")
01450                         .arg(info["type"]);
01451                 else
01452                     not_found_msg += i18n("unknown object type \"%1\"").arg(info["type"]);
01453                 not_found_msg += internalReason(&Kexi::partManager())+"<br></li>";
01454                 continue;
01455             }
01456             // * NEW
01457             if (info["action"]=="new") {
01458                 if (!newObject( i, openingCancelled) && !openingCancelled) {
01459                     not_found_msg += "<li>";
01460                     not_found_msg += (i18n("cannot create object of type \"%1\"").arg(info["type"])+
01461                         internalReason(d->prj)+"<br></li>");
01462                 }
01463                 else
01464                     d->wasAutoOpen = true;
01465                 continue;
01466             }
01467 
01468             KexiPart::Item *item = d->prj->item(i, info["name"]);
01469 
01470             if (!item) {
01471                 QString taskName;
01472                 if (info["action"]=="print-preview")
01473                     taskName = i18n("making print preview for");
01474                 else if (info["action"]=="print")
01475                     taskName = i18n("printing");
01476                 else if (info["action"]=="execute")
01477                     taskName = i18n("\"executing object\" action", "executing");
01478                 else 
01479                     taskName = i18n("opening");
01480 
01481                 not_found_msg += (QString("<li>")+ taskName + " \"" + info["name"] + "\" - ");
01482                 if ("table"==info["type"].lower())
01483                     not_found_msg += i18n("table not found");
01484                 else if ("query"==info["type"].lower())
01485                     not_found_msg += i18n("query not found");
01486                 else if ("macro"==info["type"].lower())
01487                     not_found_msg += i18n("macro not found");
01488                 else if ("script"==info["type"].lower())
01489                     not_found_msg += i18n("script not found");
01490                 else
01491                     not_found_msg += i18n("object not found");
01492                 not_found_msg += (internalReason(d->prj)+"<br></li>");
01493                 continue;
01494             }
01495             // * EXECUTE, PRINT, PRINT PREVIEW
01496             if (info["action"]=="execute") {
01497                 tristate res = executeItem(item);
01498                 if (false == res) {
01499                     not_found_msg += ( QString("<li>\"")+ info["name"] + "\" - " + i18n("cannot execute object")+
01500                     internalReason(d->prj)+"<br></li>" );
01501                 }
01502                 continue;
01503             }
01504             else if (info["action"]=="print") {
01505                 tristate res = printItem(item);
01506                 if (false == res) {
01507                     not_found_msg += ( QString("<li>\"")+ info["name"] + "\" - " + i18n("cannot print object")+
01508                     internalReason(d->prj)+"<br></li>" );
01509                 }
01510                 continue;
01511             }
01512             else if (info["action"]=="print-preview") {
01513                 tristate res = printPreviewForItem(item);
01514                 if (false == res) {
01515                     not_found_msg += ( QString("<li>\"")+ info["name"] + "\" - " + i18n("cannot make print preview of object")+
01516                     internalReason(d->prj)+"<br></li>" );
01517                 }
01518                 continue;
01519             }
01520 
01521             int viewMode;
01522             if (info["action"]=="open")
01523                 viewMode = Kexi::DataViewMode;
01524             else if (info["action"]=="design")
01525                 viewMode = Kexi::DesignViewMode;
01526             else if (info["action"]=="edittext")
01527                 viewMode = Kexi::TextViewMode;
01528             else
01529                 continue; //sanity
01530 
01531             QString openObjectMessage;
01532             if (!openObject(item, viewMode, openingCancelled, 0, &openObjectMessage) 
01533                 && (!openingCancelled || !openObjectMessage.isEmpty()))
01534             {
01535                 not_found_msg += (QString("<li>\"")+ info["name"] + "\" - ");
01536                 if (openObjectMessage.isEmpty())
01537                     not_found_msg += i18n("cannot open object");
01538                 else
01539                     not_found_msg += openObjectMessage;
01540                 not_found_msg += internalReason(d->prj) + "<br></li>";
01541                 continue;
01542             }
01543             else {
01544                 d->wasAutoOpen = true;
01545             }
01546         }
01547     }
01548     enableMessages( true );
01549 //  d->disableErrorMessages = false;
01550 
01551     if (!not_found_msg.isEmpty())
01552         showErrorMessage(i18n("You have requested selected objects to be automatically opened "
01553             "or processed on startup. Several objects cannot be opened or processed."),
01554             QString("<ul>%1</ul>").arg(not_found_msg) );
01555 
01556     d->updatePropEditorVisibility(d->curDialog ? d->curDialog->currentViewMode() : 0);
01557 #if defined(KDOCKWIDGET_P)
01558     if (d->propEditor) {
01559                 KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
01560                 KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01561                 if(ds)
01562                     ds->setSeparatorPosInPercent(d->config->readNumEntry("RightDockPosition", 80/* % */));
01563     }
01564 #endif
01565 
01566     updateAppCaption();
01567 
01568 //  d->navToolWindow->wrapperWidget()->setFixedWidth(200);
01569 //js TODO: make visible FOR OTHER MODES if needed
01570     if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
01571         //make docks visible again
01572         if (!d->navToolWindow->wrapperWidget()->isVisible())
01573             static_cast<KDockWidget*>(d->navToolWindow->wrapperWidget())->makeDockVisible();
01574 //      if (!d->propEditorToolWindow->wrapperWidget()->isVisible())
01575 //          static_cast<KDockWidget*>(d->propEditorToolWindow->wrapperWidget())->makeDockVisible();
01576     }
01577 
01578     //  if (!d->prj->data()->autoopenObjects.isEmpty())
01579     d->restoreNavigatorWidth();
01580 
01581 #ifndef PROPEDITOR_VISIBILITY_CHANGES
01582 //  KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
01583 //  KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01584 //  const int pos = ds->separatorPos();
01585 
01586     //if (!d->curDialog || d->curDialog->currentViewMode()==Kexi::DataViewMode)
01587 //      d->propEditorToolWindow->hide();
01588 
01589 //  ds->setSeparatorPos( pos, true );
01590 #endif
01591     if (d->nav) {
01592         d->nav->updateGeometry();
01593     }
01594     qApp->processEvents();
01595     emit projectOpened();
01596 }
01597 
01598 tristate KexiMainWindowImpl::closeProject()
01599 {
01600 #ifndef KEXI_NO_PENDING_DIALOGS
01601     if (d->pendingDialogsExist()) {
01602         kdDebug() << "KexiMainWindowImpl::closeProject() pendingDialogsExist..." << endl;
01603         d->actionToExecuteWhenPendingJobsAreFinished = Private::CloseProjectAction;
01604         return cancelled;
01605     }
01606 #endif
01607 
01608     //only save nav. visibility setting is project is opened
01609     d->saveSettingsForShowProjectNavigator = d->prj && d->isProjectNavigatorVisible;
01610 
01611     if (!d->prj)
01612         return true;
01613 
01614     {
01615         // make sure the project can be closed
01616         bool cancel = false;
01617         emit acceptProjectClosingRequested(cancel);
01618         if (cancel)
01619             return cancelled;
01620     }
01621 
01622     d->dialogExistedBeforeCloseProject = !d->curDialog.isNull();
01623 
01624 #if defined(KDOCKWIDGET_P)
01625     //remember docks position - will be used on storeSettings()
01626     if (d->propEditor) {
01627         KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
01628         KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01629         if (ds)
01630             d->propEditorDockSeparatorPos = ds->separatorPosInPercent();
01631     }
01632     if (d->nav) {
01633 //      makeDockInvisible( manager()->findWidgetParentDock(d->propEditor) );
01634 
01635         if (d->propEditor) {
01636             if (d->openedDialogsCount() == 0)
01637                 makeWidgetDockVisible(d->propEditorTabWidget);
01638             KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
01639             KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01640             if(ds)
01641                 ds->setSeparatorPosInPercent(80);
01642         }
01643 
01644         KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
01645         KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01646         int dwWidth = dw->width();
01647         if (ds) {
01648                 if (d->openedDialogsCount()!=0 && d->propEditorTabWidget && d->propEditorTabWidget->isVisible())
01649                     d->navDockSeparatorPos = ds->separatorPosInPercent();
01650                 else
01651                     d->navDockSeparatorPos = (100 * dwWidth) / width();
01652 
01653 //              int navDockSeparatorPosWithAutoOpen = (100 * dw->width()) / width() + 4;
01654 //              d->navDockSeparatorPos = (100 * dw->width()) / width() + 1;
01655         }
01656     }
01657 #endif
01658 
01659     //close each window, optionally asking if user wants to close (if data changed)
01660     while (!d->curDialog.isNull()) {
01661         tristate res = closeDialog( d->curDialog );
01662         if (!res || ~res)
01663             return res;
01664     }
01665 
01666     // now we will close for sure
01667     emit beforeProjectClosing();
01668 
01669     if (!d->prj->closeConnection())
01670         return false;
01671 
01672     if(d->nav)
01673     {
01674         d->navWasVisibleBeforeProjectClosing = manager()->findWidgetParentDock(d->nav)->isVisible();
01675         d->nav->clear();
01676 #if 0 //do not confuse users 
01677         d->navToolWindow->hide();
01678 #endif
01679     }
01680 
01681     if (d->propEditor)
01682         makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
01683 
01684 //  if(d->propEditorToolWindow)
01685     //  d->propEditorToolWindow->hide();
01686 
01687     d->clearDialogs(); //sanity!
01688     delete d->prj;
01689     d->prj=0;
01690 
01691 //  Kexi::partManager().unloadAllParts();
01692 
01693     updateReadOnlyState();
01694     invalidateActions();
01695 //  if (!userMode())
01696         updateAppCaption();
01697 
01698     emit projectClosed();
01699     return true;
01700 }
01701 
01702 void KexiMainWindowImpl::initContextHelp() {
01703 #ifndef KEXI_NO_CTXT_HELP
01704     d->ctxHelp=new KexiContextHelp(this,this);
01705 /*todo
01706     d->ctxHelp->setContextHelp(i18n("Welcome"),i18n("The <B>KEXI team</B> wishes you a lot of productive work, "
01707         "with this product. <BR><HR><BR>If you have found a <B>bug</B> or have a <B>feature</B> request, please don't "
01708         "hesitate to report it at our <A href=\"http://www.kexi-project.org/cgi-bin/bug.pl\"> issue "
01709         "tracking system </A>.<BR><HR><BR>If you would like to <B>join</B> our effort, the <B>development</B> documentation "
01710         "at <A href=\"http://www.kexi-project.org\">www.kexi-project.org</A> is a good starting point."),0);
01711 */
01712     addToolWindow(d->ctxHelp,KDockWidget::DockBottom | KDockWidget::DockLeft,getMainDockWidget(),20);
01713 #endif
01714 }
01715 
01716 void KexiMainWindowImpl::initNavigator()
01717 {
01718     if (!d->isProjectNavigatorVisible)
01719         return;
01720 
01721     if(!d->nav)
01722     {
01723         d->nav = new KexiBrowser(this, this);
01724         d->nav->installEventFilter(this);
01725         d->navToolWindow = addToolWindow(d->nav, KDockWidget::DockLeft, getMainDockWidget(), 20/*, lv, 35, "2"*/);
01726 //      d->navToolWindow->hide();
01727 
01728         connect(d->nav,SIGNAL(openItem(KexiPart::Item*,int)),this,SLOT(openObject(KexiPart::Item*,int)));
01729         connect(d->nav,SIGNAL(openOrActivateItem(KexiPart::Item*,int)),
01730             this,SLOT(openObjectFromNavigator(KexiPart::Item*,int)));
01731         connect(d->nav,SIGNAL(newItem( KexiPart::Info* )),
01732             this,SLOT(newObject(KexiPart::Info*)));
01733         connect(d->nav,SIGNAL(removeItem(KexiPart::Item*)),
01734             this,SLOT(removeObject(KexiPart::Item*)));
01735         connect(d->nav,SIGNAL(renameItem(KexiPart::Item*,const QString&, bool&)),
01736             this,SLOT(renameObject(KexiPart::Item*,const QString&, bool&)));
01737         connect(d->nav,SIGNAL(executeItem(KexiPart::Item*)),
01738             this,SLOT(executeItem(KexiPart::Item*)));
01739         connect(d->nav,SIGNAL(exportItemAsDataTable(KexiPart::Item*)),
01740             this,SLOT(exportItemAsDataTable(KexiPart::Item*)));
01741         connect(d->nav,SIGNAL(printItem( KexiPart::Item* )),
01742             this,SLOT(printItem(KexiPart::Item*)));
01743         connect(d->nav,SIGNAL(pageSetupForItem( KexiPart::Item*)),
01744             this,SLOT(showPageSetupForItem(KexiPart::Item*)));
01745         if (d->prj) {//connect to the project
01746             connect(d->prj, SIGNAL(itemRemoved(const KexiPart::Item&)),
01747                 d->nav, SLOT(slotRemoveItem(const KexiPart::Item&)));
01748         }
01749         connect(d->nav,SIGNAL(selectionChanged(KexiPart::Item*)),
01750             this,SLOT(slotPartItemSelectedInNavigator(KexiPart::Item*)));
01751 
01752 //      d->restoreNavigatorWidth();
01753     }
01754     if(d->prj->isConnected()) {
01755         QString partManagerErrorMessages;
01756         d->nav->setProject( d->prj, QString::null/*all mimetypes*/, &partManagerErrorMessages );
01757         if (!partManagerErrorMessages.isEmpty()) {
01758             showWarningContinueMessage(partManagerErrorMessages, QString::null,
01759                 "dontShowWarningsRelatedToPluginsLoading");
01760         }
01761     }
01762     connect(d->prj, SIGNAL(newItemStored(KexiPart::Item&)), d->nav, SLOT(addItem(KexiPart::Item&)));
01763     d->nav->setFocus();
01764 
01765     if (d->forceShowProjectNavigatorOnCreation) {
01766         slotViewNavigator();
01767         d->forceShowProjectNavigatorOnCreation = false;
01768     }
01769     else if (d->forceHideProjectNavigatorOnCreation) {
01770         d->navToolWindow->hide();
01771 //      makeDockInvisible( manager()->findWidgetParentDock(d->nav) );
01772         d->forceHideProjectNavigatorOnCreation = false;
01773     }
01774 
01775     invalidateActions();
01776 }
01777 
01778 void KexiMainWindowImpl::slotLastActions()
01779 {
01780 #if defined(KDOCKWIDGET_P)
01781     if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
01782 //      KDockWidget *dw = (KDockWidget *)d->propEditor->parentWidget();
01783         //KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01784 //      Q_UNUSED(ds);
01785 //1     ds->resize(ds->width()*3, ds->height());
01786 //1     ds->setSeparatorPos(30, true);
01787 //1     ds->setForcedFixedWidth( dw, 200 );
01788     }
01789 #endif
01790 #ifdef Q_WS_WIN
01791     showMaximized();//js: workaround for not yet completed layout settings storage on win32
01792 #endif
01793 }
01794 
01795 void KexiMainWindowImpl::initPropertyEditor()
01796 {
01797     if (!d->propEditor) {
01798 //TODO: FIX LAYOUT PROBLEMS
01799         d->propEditorTabWidget = new KTabWidget(this);
01800         d->propEditorTabWidget->hide();
01801         d->propEditor = new KexiPropertyEditorView(this, d->propEditorTabWidget);
01802         d->propEditorTabWidget->setCaption(d->propEditor->caption());
01803         d->propEditorTabWidget->addTab(d->propEditor, i18n("Properties"));
01804         d->propEditor->installEventFilter(this);
01805         d->propEditorToolWindow = addToolWindow(d->propEditorTabWidget,
01806             KDockWidget::DockRight, getMainDockWidget(), 20);
01807 
01808         d->config->setGroup("PropertyEditor");
01809         int size = d->config->readNumEntry("FontSize", -1);
01810         QFont f( Kexi::smallFont() );
01811         if (size>0)
01812             f.setPixelSize( size );
01813         d->propEditorTabWidget->setFont(f);
01814 
01815         if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
01816         KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
01817     #if defined(KDOCKWIDGET_P)
01818             KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
01819 //          ds->setKeepSize(true);
01820             makeWidgetDockVisible(d->propEditorTabWidget);
01821     //      ds->show();
01822         //  ds->resize(400, ds->height());
01823     //      ds->setSeparatorPos(400, true);
01824     //      ds->setForcedFixedWidth( dw, 400 );
01825     //      ds->setSeparatorPos(600, true);
01826 
01827 
01828             d->config->setGroup("MainWindow");
01829             ds->setSeparatorPosInPercent(d->config->readNumEntry("RightDockPosition", 80/* % */));
01830 //          makeDockInvisible( manager()->findWidgetParentDock(d->propEditor) );
01831 
01832     //      ds->setForcedFixedWidth( dw, d->config->readNumEntry("RightDockPosition", 80) );
01833         //  ds->resize(400, ds->height());
01834         //  dw->resize(400, dw->height());
01835     #endif
01836 
01837     //1     dw->setMinimumWidth(200);
01838 
01839     //  ds->setSeparatorPos(d->propEditor->sizeHint().width(), true);
01840 
01841             //heh, this is for IDEAl only, I suppose?
01842     //js        if (m_rightContainer) {
01843     //js            m_rightContainer->setForcedFixedWidth( 400 );
01844     //js        }
01845         }
01846 
01847     //  int w = d->propEditor->width();
01848     /*    KMdiToolViewAccessor *tmp=createToolWindow();
01849             tmp->setWidgetToWrap(d->propEditor);
01850         d->propEditor->show(); // I'm not sure, if this is a bug in kdockwidget, which I would better fix there
01851             tmp->show(KDockWidget::DockRight,getMainDockWidget(),20);
01852     */
01853     }
01854 //  makeDockInvisible(manager()->findWidgetParentDock(d->propEditorTabWidget));
01855 }
01856 
01857 void KexiMainWindowImpl::slotPartLoaded(KexiPart::Part* p)
01858 {
01859     if (!p)
01860         return;
01861     connect(p, SIGNAL(newObjectRequest(KexiPart::Info*)),
01862         this, SLOT(newObject(KexiPart::Info*)));
01863     p->createGUIClients(this);
01864 }
01865 
01867 void KexiMainWindowImpl::slotCaptionForCurrentMDIChild(bool childrenMaximized)
01868 {
01869     //js todo: allow to set custom "static" app caption
01870 
01871     KMdiChildView *view = 0L;
01872     if (!d->curDialog)
01873         view = 0;
01874     else if (d->curDialog->isAttached()) {
01875         view = d->curDialog;
01876     } else {
01877         //current dialog isn't attached! - find top level child
01878         if (m_pMdi->topChild()) {
01879             view = m_pMdi->topChild()->m_pClient;
01880             childrenMaximized = view->mdiParent()->state()==KMdiChildFrm::Maximized;
01881         }
01882         else
01883             view = 0;
01884     }
01885 
01886     if (childrenMaximized && view) {
01887         setCaption( d->curDialog->caption()
01888             + (d->appCaptionPrefix.isEmpty() ? QString::null : (QString::fromLatin1(" - ") + d->appCaptionPrefix)) );
01889     }
01890     else {
01891         setCaption( (d->appCaptionPrefix.isEmpty() ? QString::null : (d->appCaptionPrefix + QString::fromLatin1(" - ")))
01892             + d->origAppCaption );
01893     }
01894 }
01895 
01896 void KexiMainWindowImpl::updateAppCaption()
01897 {
01898     //js todo: allow to set custom "static" app caption
01899 
01900     d->appCaptionPrefix = "";
01901     if (d->prj && d->prj->data()) {//add project name
01902         d->appCaptionPrefix = d->prj->data()->caption();
01903         if (d->appCaptionPrefix.isEmpty())
01904             d->appCaptionPrefix = d->prj->data()->databaseName();
01905     }
01906 //  if (!d->appCaptionPrefix.isEmpty())
01907 //      d->appCaptionPrefix = d->appCaptionPrefix;
01908 
01909     bool max = false;
01910     if (d->curDialog && d->curDialog->mdiParent())
01911         max = d->curDialog->mdiParent()->state()==KMdiChildFrm::Maximized;
01912 
01913     slotCaptionForCurrentMDIChild(max);
01914 /*
01915     KMdiChildView *view;
01916     if (!d->curDialog)
01917         view = 0;
01918     else if (d->curDialog->isAttached()) {
01919         view = d->curDialog;
01920     } else {
01921         //current dialog isn't attached! - find top level child
01922         if (m_pMdi->topChild()) {
01923             view = m_pMdi->topChild()->m_pClient;
01924         }
01925         else
01926             view = 0;
01927     }
01928 
01929     kApp->setCaption( d->appCaption );
01930     if (view && view->mdiParent()->state()==KMdiChildFrm::Maximized) {
01931         setCaption( view->caption() );
01932     }
01933     else {
01934         setCaption( d->appCaption );
01935     }*/
01936 }
01937 
01938 void KexiMainWindowImpl::slotNoMaximizedChildFrmLeft(KMdiChildFrm*)
01939 {
01940     slotCaptionForCurrentMDIChild(false);
01941 }
01942 
01943 void KexiMainWindowImpl::slotLastChildViewClosed() //slotLastChildFrmClosed()
01944 {
01945     if (m_pDocumentViews->count()>0) //a fix for KMDI bug (will be fixed in KDE 3.4)
01946         return;
01947 
01948     slotCaptionForCurrentMDIChild(false);
01949     activeWindowChanged(0);
01950 
01951 //js: too WEIRD if (d->propEditor)
01952 //js: too WEIRD     makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
01953 //  if (d->propEditorToolWindow)
01954     //  d->propEditorToolWindow->hide();
01955 }
01956 
01957 void KexiMainWindowImpl::slotChildViewIsDetachedNow(QWidget*)
01958 {
01959     slotCaptionForCurrentMDIChild(false);
01960 }
01961 
01962 /*void
01963 KexiMainWindowImpl::closeEvent(QCloseEvent *ev)
01964 {
01965     storeSettings();
01966 
01967     bool cancelled = false;
01968     if (!closeProject(cancelled)) {
01969         //todo: error message
01970         return;
01971     }
01972     if (cancelled) {
01973         ev->ignore();
01974         return;
01975     }
01976 
01977     ev->accept();
01978 }*/
01979 
01980 bool
01981 KexiMainWindowImpl::queryClose()
01982 {
01983 #ifndef KEXI_NO_PENDING_DIALOGS
01984     if (d->pendingDialogsExist()) {
01985         kdDebug() << "KexiMainWindowImpl::queryClose() pendingDialogsExist..." << endl;
01986         d->actionToExecuteWhenPendingJobsAreFinished = Private::QuitAction;
01987         return false;
01988     }
01989 #endif
01990 //  storeSettings();
01991     const tristate res = closeProject();
01992     if (~res)
01993         return false;
01994 
01995     if (res==true)
01996         storeSettings();
01997 
01998     return ! ~res;
01999 }
02000 
02001 bool
02002 KexiMainWindowImpl::queryExit()
02003 {
02004 //  storeSettings();
02005     return true;
02006 }
02007 
02008 void
02009 KexiMainWindowImpl::restoreSettings()
02010 {
02011     d->config->setGroup("MainWindow");
02012 
02013     // Saved settings
02014     applyMainWindowSettings( d->config, "MainWindow" );
02015 
02016     //small hack - set the default -- bottom
02017 //  d->config->setGroup(QString(name()) + " KMdiTaskBar Toolbar style");
02018     d->config->setGroup("MainWindow Toolbar KMdiTaskBar");
02019     const bool tbe = d->config->readEntry("Position").isEmpty();
02020     if (tbe || d->config->readEntry("Position")=="Bottom") {
02021         if (tbe)
02022             d->config->writeEntry("Position","Bottom");
02023         moveDockWindow(m_pTaskBar, DockBottom);
02024     }
02025 
02026     d->config->setGroup("MainWindow");
02027     int mdimode = d->config->readNumEntry("MDIMode", -1);//KMdi::TabPageMode);
02028 
02029     const bool showProjectNavigator = d->config->readBoolEntry("ShowProjectNavigator", true);
02030 
02031     switch(mdimode)
02032     {
02033 /*      case KMdi::ToplevelMode:
02034             switchToToplevelMode();
02035             m_pTaskBar->switchOn(true);
02036             break;*/
02037         case KMdi::ChildframeMode:
02038             switchToChildframeMode(false);
02039             m_pTaskBar->switchOn(true);
02040 
02041             // restore a possible maximized Childframe mode,
02042             // will be used in KexiMainWindowImpl::addWindow()
02043             d->maximizeFirstOpenedChildFrm = d->config->readBoolEntry("maximized childframes", true);
02044             setEnableMaximizedChildFrmMode(d->maximizeFirstOpenedChildFrm);
02045 
02046             if (!showProjectNavigator) {
02047                 //it's visible by default but we want to hide it on navigator creation
02048                 d->forceHideProjectNavigatorOnCreation = true;
02049             }
02050 
02051             break;
02052 
02053 #define DEFAULT_MDI_MODE KMdi::IDEAlMode
02054 
02055         case DEFAULT_MDI_MODE:
02056         default:
02057             switchToIDEAlMode(false);
02058             if (showProjectNavigator) {
02059                 //it's invisible by default but we want to show it on navigator creation
02060                 d->forceShowProjectNavigatorOnCreation = true;
02061             }
02062             break;
02063 /*      case KMdi::TabPageMode:
02064             switchToTabPageMode();
02065             break;
02066 */
02067     }
02068 
02069 #if 0
02070     if ( !initialGeometrySet() ) {
02071         // Default size
02072 //      int restoredWidth, restoredHeight;
02073         int scnum = QApplication::desktop()->screenNumber(parentWidget());
02074         QRect desk = QApplication::desktop()->screenGeometry(scnum);
02075 //#if KDE_IS_VERSION(3,1,90)
02076 //      restoredWidth = KGlobalSettings::screenGeometry(scnum).width();
02077     //  restoredHeight = KGlobalSettings::screenGeometry(scnum).height();
02078 //#else
02079 //      restoredWidth = QApplication::desktop()->width();
02080 //      restoredHeight = QApplication::desktop()->height();
02081 //#endif
02082 /*      if (restoredWidth > 1100) {// very big desktop ?
02083             restoredWidth = 1000;
02084             restoredHeight = 800;
02085         }
02086         if (restoredWidth > 850) {// big desktop ?
02087             restoredWidth = 800;
02088             restoredHeight = 600;
02089         }
02090         else {// small (800x600, 640x480) desktop
02091             restoredWidth = QMIN( restoredWidth, 600 );
02092             restoredHeight = QMIN( restoredHeight, 400 );
02093         }*/
02094 
02095         config->setGroup("MainWindow");
02096         QSize s ( config->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 700 ),
02097               config->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 480 ) );
02098         resize (kMin (s.width(), desk.width()), kMin(s.height(), desk.height()));
02099     }
02100 #endif
02101 }
02102 
02103 void
02104 KexiMainWindowImpl::storeSettings()
02105 {
02106     kdDebug() << "KexiMainWindowImpl::storeSettings()" << endl;
02107 
02108 //  saveWindowSize( d->config ); //instance()->config() );
02109     saveMainWindowSettings( d->config, "MainWindow" );
02110     d->config->setGroup("MainWindow");
02111     KMdi::MdiMode modeToSave = mdiMode();
02112     if (d->mdiModeToSwitchAfterRestart!=(KMdi::MdiMode)0)
02113         modeToSave = d->mdiModeToSwitchAfterRestart;
02114     if (modeToSave == DEFAULT_MDI_MODE)
02115         d->config->deleteEntry("MDIMode");
02116     else
02117         d->config->writeEntry("MDIMode", modeToSave);
02118     d->config->writeEntry("maximized childframes", isInMaximizedChildFrmMode());
02119 
02120 //  if (manager()->findWidgetParentDock(d->nav)->isVisible())
02121     if (d->saveSettingsForShowProjectNavigator) {
02122         if (d->navWasVisibleBeforeProjectClosing)
02123             d->config->deleteEntry("ShowProjectNavigator");
02124         else
02125             d->config->writeEntry("ShowProjectNavigator", false);
02126     }
02127 
02128     if (modeToSave==KMdi::ChildframeMode || modeToSave==KMdi::TabPageMode) {
02129         if (d->propEditor && d->propEditorDockSeparatorPos >= 0 && d->propEditorDockSeparatorPos <= 100) {
02130             d->config->setGroup("MainWindow");
02131             d->config->writeEntry("RightDockPosition", d->propEditorDockSeparatorPos);
02132         }
02133         else
02134             d->propEditorDockSeparatorPos = 80;
02135         if (d->nav && d->navDockSeparatorPos >= 0 && d->navDockSeparatorPos <= 100) {
02136             d->config->setGroup("MainWindow");
02137             //KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
02138             //int w = dw->width();
02139             //int ww = width();
02140             //int d1 = (100 * dw->width()) / width() + 1;
02141             //KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
02142             //int d2 = ds->separatorPosInPercent();
02143             if (d->wasAutoOpen && d->dialogExistedBeforeCloseProject) {
02144 #ifdef Q_WS_WIN
02145                 d->config->writeEntry("LeftDockPositionWithAutoOpen",
02146                     d->navDockSeparatorPos);
02147 #endif
02148 //          d->config->writeEntry("LeftDockPosition", dw->width());
02149 //          d->config->writeEntry("LeftDockPosition", d->nav->width());
02150             } else {
02151 #ifdef Q_WS_WIN
02152                 if (d->dialogExistedBeforeCloseProject)
02153                     d->config->writeEntry("LeftDockPosition", d->navDockSeparatorPos);
02154                 else
02155                     d->config->writeEntry("LeftDockPosition", qRound(double(d->navDockSeparatorPos) / 0.77
02156                      / (double(d->propEditorDockSeparatorPos) / 80) ));
02157 #endif
02158             }
02159         }
02160     }
02161 
02162     if (d->propEditor) {
02163         d->config->setGroup("PropertyEditor");
02164         d->config->writeEntry("FontSize", d->propEditorTabWidget->font().pixelSize());
02165     }
02166 }
02167 
02168 void
02169 KexiMainWindowImpl::restoreWindowConfiguration(KConfig *config)
02170 {
02171     kdDebug()<<"preparing session restoring"<<endl;
02172 
02173     config->setGroup("MainWindow");
02174 
02175     QString dockGrp;
02176 
02177     if (kapp->isRestored())
02178         dockGrp=config->group()+"-Docking";
02179     else
02180         dockGrp="MainWindow0-Docking";
02181 
02182     if (config->hasGroup(dockGrp))
02183         readDockConfig(config,dockGrp);
02184 }
02185 
02186 void
02187 KexiMainWindowImpl::storeWindowConfiguration(KConfig *config)
02188 {
02189     kdDebug()<<"preparing session saving"<<endl;
02190     config->setGroup("MainWindow");
02191     QString dockGrp;
02192 
02193 #if KDE_IS_VERSION(3,1,9) && !defined(Q_WS_WIN)
02194     if (kapp->sessionSaving())
02195         dockGrp=config->group()+"-Docking";
02196     else
02197 #endif
02198         dockGrp="MainWindow0-Docking";
02199 
02200     kdDebug()<<"Before write dock config"<<endl;
02201     writeDockConfig(config,dockGrp);
02202     kdDebug()<<"After write dock config"<<endl;
02203 }
02204 
02205 void
02206 KexiMainWindowImpl::readProperties(KConfig *config) {
02207     restoreWindowConfiguration(config);
02208 }
02209 
02210 void
02211 KexiMainWindowImpl::saveProperties(KConfig *config)
02212 {
02213     storeWindowConfiguration(config);
02214 //        m_docManager->saveDocumentList (config);
02215   //      m_projectManager->saveProjectList (config);
02216 }
02217 
02218 void
02219 KexiMainWindowImpl::saveGlobalProperties( KConfig* sessionConfig ) {
02220     storeWindowConfiguration(sessionConfig);
02221 }
02222 
02223 void
02224 KexiMainWindowImpl::registerChild(KexiDialogBase *dlg)
02225 {
02226     kdDebug() << "KexiMainWindowImpl::registerChild()" << endl;
02227     connect(dlg, SIGNAL(activated(KMdiChildView *)),
02228         this, SLOT(activeWindowChanged(KMdiChildView *)));
02229     connect(dlg, SIGNAL(dirtyChanged(KexiDialogBase*)),
02230         this, SLOT(slotDirtyFlagChanged(KexiDialogBase*)));
02231 
02232 //  connect(dlg, SIGNAL(childWindowCloseRequest(KMdiChildView *)), this, SLOT(childClosed(KMdiChildView *)));
02233     if(dlg->id() != -1) {
02234         d->insertDialog(dlg);
02235     }
02236     kdDebug() << "KexiMainWindowImpl::registerChild() ID = " << dlg->id() << endl;
02237 
02238     if (m_mdiMode==KMdi::ToplevelMode || m_mdiMode==KMdi::ChildframeMode) {//kmdi fix
02239         //js TODO: check if taskbar is switched in menu
02240         if (m_pTaskBar && !m_pTaskBar->isSwitchedOn())
02241             m_pTaskBar->switchOn(true);
02242     }
02243     //KMdiChildFrm *frm = dlg->mdiParent();
02244     //if (frm) {
02245 //      dlg->setMargin(20);
02246         //dlg->setLineWidth(20);
02247     //}
02248 }
02249 
02250 void
02251 KexiMainWindowImpl::updateDialogViewGUIClient(KXMLGUIClient *viewClient)
02252 {
02253     if (viewClient!=d->curDialogViewGUIClient) {
02254         //view clients differ
02255         kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old view gui client:"
02256             <<(d->curDialogViewGUIClient ? d->curDialogViewGUIClient->xmlFile() : "")
02257             <<" new view gui client: "<<( viewClient ? viewClient->xmlFile() : "") <<endl;
02258         if (d->curDialogViewGUIClient) {
02259             guiFactory()->removeClient(d->curDialogViewGUIClient);
02260         }
02261         if (viewClient) {
02262             if (d->closedDialogViewGUIClient) {
02263                 //ooh, there is a client which dialog is already closed -- BUT it is the same client as our
02264                 //so: give up
02265             }
02266             else {
02267                 guiFactory()->addClient(viewClient);
02268             }
02269         }
02270     }
02271 }
02272 
02273 void KexiMainWindowImpl::updateCustomPropertyPanelTabs(KexiDialogBase *prevDialog, int prevViewMode)
02274 {
02275     updateCustomPropertyPanelTabs(
02276         prevDialog ? prevDialog->part() : 0,
02277         prevDialog ? prevDialog->currentViewMode() : prevViewMode,
02278         d->curDialog ? d->curDialog->part() : 0,
02279         d->curDialog ? d->curDialog->currentViewMode() : Kexi::NoViewMode
02280     );
02281 }
02282 
02283 void KexiMainWindowImpl::updateCustomPropertyPanelTabs(
02284     KexiPart::Part *prevDialogPart, int prevViewMode, KexiPart::Part *curDialogPart, int curViewMode )
02285 {
02286     if (!d->propEditorTabWidget)
02287         return;
02288 
02289     if (!curDialogPart
02290         || (/*prevDialogPart &&*/ curDialogPart
02291             && (prevDialogPart!=curDialogPart || prevViewMode!=curViewMode)
02292          ))
02293     {
02294         if (d->partForPreviouslySetupPropertyPanelTabs) {
02295             //remember current page number for this part
02296             if (prevViewMode==Kexi::DesignViewMode && 
02297                 ((KexiPart::Part*)d->partForPreviouslySetupPropertyPanelTabs != curDialogPart) //part changed
02298                 || curViewMode!=Kexi::DesignViewMode) //..or switching to other view mode
02299             {
02300                 d->recentlySelectedPropertyPanelPages.insert( d->partForPreviouslySetupPropertyPanelTabs, 
02301                     d->propEditorTabWidget->currentPageIndex() );
02302             }
02303         }
02304         
02305         //delete old custom tabs (other than 'property' tab)
02306         const uint count = d->propEditorTabWidget->count();
02307         for (uint i=1; i < count; i++)
02308             d->propEditorTabWidget->removePage( d->propEditorTabWidget->page(1) );
02309     }
02310 
02311     //don't change anything if part is not switched nor view mode changed
02312     if ((!prevDialogPart && !curDialogPart)
02313         || (prevDialogPart == curDialogPart && prevViewMode==curViewMode)
02314         || (curDialogPart && curViewMode!=Kexi::DesignViewMode))
02315     {
02316         //new part for 'previously setup tabs'
02317         d->partForPreviouslySetupPropertyPanelTabs = curDialogPart;
02318         return;
02319     }
02320 
02321     if (curDialogPart) {
02322         //recreate custom tabs
02323         curDialogPart->setupCustomPropertyPanelTabs(d->propEditorTabWidget, this);
02324 
02325         //restore current page number for this part
02326         if (d->recentlySelectedPropertyPanelPages.contains( curDialogPart )) {
02327             d->propEditorTabWidget->setCurrentPage( 
02328                 d->recentlySelectedPropertyPanelPages[ curDialogPart ] 
02329             );
02330         }
02331     }
02332 
02333     //new part for 'previously setup tabs'
02334     d->partForPreviouslySetupPropertyPanelTabs = curDialogPart;
02335 }
02336 
02337 void KexiMainWindowImpl::activeWindowChanged(KMdiChildView *v)
02338 {
02339     KexiDialogBase *dlg = static_cast<KexiDialogBase *>(v);
02340     kdDebug() << "KexiMainWindowImpl::activeWindowChanged() to = " << (dlg ? dlg->caption() : "<none>") << endl;
02341 
02342     KXMLGUIClient *client=0; //common for all views
02343     KXMLGUIClient *viewClient=0; //specific for current dialog's view
02344     KexiDialogBase* prevDialog = d->curDialog;
02345 
02346     if (!dlg)
02347         client=0;
02348     else if ( dlg->isRegistered()) {
02349 //      client=dlg->guiClient();
02350         client=dlg->commonGUIClient();
02351         viewClient=dlg->guiClient();
02352         if (d->closedDialogGUIClient) {
02353             if (client!=d->closedDialogGUIClient) {
02354                 //ooh, there is a client which dialog is already closed -- and we don't want it
02355                 guiFactory()->removeClient(d->closedDialogGUIClient);
02356                 d->closedDialogGUIClient=0;
02357             }
02358         }
02359         if (d->closedDialogViewGUIClient) {
02360             if (viewClient!=d->closedDialogViewGUIClient) {
02361                 //ooh, there is a client which dialog is already closed -- and we don't want it
02362                 guiFactory()->removeClient(d->closedDialogViewGUIClient);
02363                 d->closedDialogViewGUIClient=0;
02364             }
02365         }
02366         if (client!=d->curDialogGUIClient) {
02367             //clients differ
02368             kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old gui client:"
02369                 <<(d->curDialogGUIClient ? d->curDialogGUIClient->xmlFile() : "")
02370                 <<" new gui client: "<<( client ? client->xmlFile() : "") <<endl;
02371             if (d->curDialogGUIClient) {
02372                 guiFactory()->removeClient(d->curDialogGUIClient);
02373                 d->curDialog->detachFromGUIClient();
02374             }
02375             if (client) {
02376                 if (d->closedDialogGUIClient) {
02377                     //ooh, there is a client which dialog is already closed -- BUT it is the same client as our
02378                     //so: give up
02379                 }
02380                 else {
02381                     guiFactory()->addClient(client);
02382                 }
02383                 dlg->attachToGUIClient();
02384             }
02385         } else {
02386             //clients are the same
02387             if ((KexiDialogBase*)d->curDialog!=dlg) {
02388                 if (d->curDialog)
02389                     d->curDialog->detachFromGUIClient();
02390                 if (dlg)
02391                     dlg->attachToGUIClient();
02392             }
02393         }
02394         updateDialogViewGUIClient(viewClient);
02395 /*      if (viewClient!=d->curDialogViewGUIClient) {
02396             //view clients differ
02397             kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old view gui client:"
02398                 <<d->curDialogViewGUIClient<<" new view gui client: "<<viewClient<<endl;
02399             if (d->curDialogViewGUIClient) {
02400                 guiFactory()->removeClient(d->curDialogViewGUIClient);
02401             }
02402             if (viewClient) {
02403                 if (d->closedDialogViewGUIClient) {
02404                     //ooh, there is a client which dialog is already closed -- BUT it is the same client as our
02405                     //so: give up
02406                 }
02407                 else {
02408                     guiFactory()->addClient(viewClient);
02409                 }
02410             }
02411         }*/
02412     }
02413     bool update_dlg_caption = dlg && dlg!=(KexiDialogBase*)d->curDialog && dlg->mdiParent();
02414 
02415     if (d->curDialogGUIClient && !client)
02416         guiFactory()->removeClient(d->curDialogGUIClient);
02417     d->curDialogGUIClient=client;
02418 
02419     if (d->curDialogViewGUIClient && !viewClient)
02420         guiFactory()->removeClient(d->curDialogViewGUIClient);
02421     d->curDialogViewGUIClient=viewClient;
02422 
02423     bool dialogChanged = ((KexiDialogBase*)d->curDialog)!=dlg;
02424 
02425     if (dialogChanged) {
02426         if (d->curDialog) {
02427             //inform previously activated dialog about deactivation
02428             d->curDialog->deactivate();
02429         }
02430     }
02431     d->curDialog=dlg;
02432 
02433 //moved below:  propertySetSwitched(d->curDialog);
02434 
02435     updateCustomPropertyPanelTabs(prevDialog, prevDialog ? prevDialog->currentViewMode() : Kexi::NoViewMode);
02436 
02437     // inform the current view of the new dialog about property switching
02438     // (this will also call KexiMainWindowImpl::propertySetSwitched() to update the current property editor's set
02439     if (dialogChanged && d->curDialog)
02440         d->curDialog->selectedView()->propertySetSwitched();
02441 
02442     if (dialogChanged) {
02443 //      invalidateSharedActions();
02444         //update property editor's contents...
02445 //      if ((KexiPropertyBuffer*)d->propBuffer!=d->curDialog->propertyBuffer()) {
02446 //      propertyBufferSwitched();//d->curDialog);
02447 //          d->propBuffer = d->curDialog->propertyBuffer();
02448 //          d->propEditor->editor()->setBuffer( d->propBuffer );
02449 //      }
02450         if (d->curDialog && d->curDialog->currentViewMode()!=0) //on opening new dialog it can be 0; we don't want this
02451             d->updatePropEditorVisibility(d->curDialog->currentViewMode());
02452     }
02453 
02454     //update caption...
02455     if (update_dlg_caption) {//d->curDialog is != null for sure
02456         slotCaptionForCurrentMDIChild(d->curDialog->mdiParent()->state()==KMdiChildFrm::Maximized);
02457     }
02458 //  if (!d->curDialog.isNull())
02459 //      d->last_checked_mode = d->actions_for_view_modes[ d->curDialog->currentViewMode() ];
02460     invalidateViewModeActions();
02461     invalidateActions();
02462     d->updateFindDialogContents();
02463     if (dlg)
02464         dlg->setFocus();
02465 }
02466 
02467 bool
02468 KexiMainWindowImpl::activateWindow(int id)
02469 {
02470     kdDebug() << "KexiMainWindowImpl::activateWindow()" << endl;
02471 #ifndef KEXI_NO_PENDING_DIALOGS
02472     Private::PendingJobType pendingType;
02473     return activateWindow( d->openedDialogFor( id, pendingType ) );
02474 #else
02475     return activateWindow( d->openedDialogFor( id ) );
02476 #endif
02477 }
02478 
02479 bool
02480 KexiMainWindowImpl::activateWindow(KexiDialogBase *dlg)
02481 {
02482     kdDebug() << "KexiMainWindowImpl::activateWindow(KexiDialogBase *)" << endl;
02483     if(!dlg)
02484         return false;
02485 
02486     d->focus_before_popup = dlg;
02487     dlg->activate();
02488     return true;
02489 }
02490 
02491 void
02492 KexiMainWindowImpl::childClosed(KMdiChildView *v)
02493 {
02494     KexiDialogBase *dlg = static_cast<KexiDialogBase *>(v);
02495     d->removeDialog(dlg->id());
02496 #ifndef KEXI_NO_PENDING_DIALOGS
02497     d->removePendingDialog(dlg->id());
02498 #endif
02499 
02500     //focus navigator if nothing else available
02501     if (d->openedDialogsCount() == 0)
02502         d->nav->setFocus();
02503 }
02504 
02505 void
02506 KexiMainWindowImpl::slotShowSettings()
02507 {
02508     KEXI_UNFINISHED(d->action_configure->text());
02509 //TODO  KexiSettings s(this);
02510 //  s.exec();
02511 }
02512 
02513 void
02514 KexiMainWindowImpl::slotConfigureKeys()
02515 {
02516 /*    KKeyDialog dlg;
02517     dlg.insert( actionCollection() );
02518     dlg.configure();*/
02519     KKeyDialog::configure( actionCollection(), false/*bAllowLetterShortcuts*/, this );
02520 }
02521 
02522 void
02523 KexiMainWindowImpl::slotConfigureToolbars()
02524 {
02525     KEditToolbar edit(factory());
02526 //    connect(&edit,SIGNAL(newToolbarConfig()),this,SLOT(slotNewToolbarConfig()));
02527     (void) edit.exec();
02528 }
02529 
02530 void
02531 KexiMainWindowImpl::slotProjectNew()
02532 {
02533     if (!d->prj) {
02534         //create within this instance
02535         createBlankProject();
02536         return;
02537     }
02538 //TODO use KexiStartupDialog(KexiStartupDialog::Templates...)
02539 
02540     bool cancel;
02541     QString fileName;
02542     KexiProjectData *new_data = createBlankProjectData(
02543         cancel,
02544         false, /* do not confirm prj overwrites: user will be asked on process startup */
02545         &fileName //shortcut fname
02546     );
02547     if (!new_data)
02548         return;
02549 
02550   QStringList args;
02551     args << qApp->applicationFilePath() << "-create-opendb";
02552     if (new_data->connectionData()->fileName().isEmpty()) {
02553         //server based - pass .kexic file
02554         if (fileName.isEmpty())
02555             return;
02556         args << new_data->databaseName() << fileName;
02557         //args << "--skip-conn-dialog"; //user does not expect conn. dialog to be shown here
02558     }
02559     else {
02560         //file based
02561         fileName = new_data->connectionData()->fileName();
02562         args << fileName;
02563     }
02564 //todo:         pass new_data->caption()
02565     //start new instance
02567     QProcess proc(args, this, "process");
02568     proc.setCommunication((QProcess::Communication)0);
02569 //      proc.setWorkingDirectory( QFileInfo(new_data->connectionData()->fileName()).dir(true) );
02570     proc.setWorkingDirectory( QFileInfo(fileName).dir(true) );
02571     if (!proc.start()) {
02572             d->showStartProcessMsg(args);
02573     }
02574     delete new_data;
02575 }
02576 
02577 void
02578 KexiMainWindowImpl::createKexiProject(KexiProjectData* new_data)
02579 {
02580     d->prj = new KexiProject( new_data, this );
02581 //  d->prj = ::createKexiProject(new_data);
02582 //provided by KexiMessageHandler    connect(d->prj, SIGNAL(error(const QString&,KexiDB::Object*)), this, SLOT(showErrorMessage(const QString&,KexiDB::Object*)));
02583 //provided by KexiMessageHandler    connect(d->prj, SIGNAL(error(const QString&,const QString&)), this, SLOT(showErrorMessage(const QString&,const QString&)));
02584     connect(d->prj, SIGNAL(itemRenamed(const KexiPart::Item&, const QCString&)), this, SLOT(slotObjectRenamed(const KexiPart::Item&, const QCString&)));
02585 
02586     if (d->nav)
02587         connect(d->prj, SIGNAL(itemRemoved(const KexiPart::Item&)), d->nav, SLOT(slotRemoveItem(const KexiPart::Item&)));
02588 }
02589 
02590 KexiProjectData*
02591 KexiMainWindowImpl::createBlankProjectData(bool &cancelled, bool confirmOverwrites, 
02592     QString* shortcutFileName)
02593 {
02594     cancelled = false;
02595     KexiNewProjectWizard wiz(Kexi::connset(), 0, "KexiNewProjectWizard", true);
02596     wiz.setConfirmOverwrites(confirmOverwrites);
02597     if (wiz.exec() != QDialog::Accepted) {
02598         cancelled=true;
02599         return 0;
02600     }
02601 
02602     KexiProjectData *new_data;
02603 
02604     if (shortcutFileName)
02605         *shortcutFileName = QString::null;
02606     if (wiz.projectConnectionData()) {
02607         //server-based project
02608         KexiDB::ConnectionData *cdata = wiz.projectConnectionData();
02609         kdDebug() << "DBNAME: " << wiz.projectDBName() << " SERVER: " << cdata->serverInfoString() << endl;
02610         new_data = new KexiProjectData( *cdata, wiz.projectDBName(), wiz.projectCaption() );
02611         if (shortcutFileName)
02612             *shortcutFileName = Kexi::connset().fileNameForConnectionData(cdata); 
02613     }
02614     else if (!wiz.projectDBName().isEmpty()) {
02615         //file-based project
02616         KexiDB::ConnectionData cdata;
02617         cdata.caption = wiz.projectCaption();
02618         cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName();
02619         cdata.setFileName( wiz.projectDBName() );
02620         new_data = new KexiProjectData( cdata, wiz.projectDBName(), wiz.projectCaption() );
02621     }
02622     else {
02623         cancelled = true;
02624         return 0;
02625     }
02626     return new_data;
02627 }
02628 
02629 tristate
02630 KexiMainWindowImpl::createBlankProject()
02631 {
02632     bool cancel;
02633     KexiProjectData *new_data = createBlankProjectData(cancel);
02634     if (cancel)
02635         return cancelled;
02636     if (!new_data)
02637         return false;
02638 
02639     createKexiProject( new_data );
02640 
02641     tristate res = d->prj->create(true /*overwrite*/ );
02642     if (res != true) {
02643         delete d->prj;
02644         d->prj = 0;
02645         return res;
02646     }
02647     kdDebug() << "KexiMainWindowImpl::slotProjectNew(): new project created --- " << endl;
02648     initNavigator();
02649     Kexi::recentProjects().addProjectData( new_data );
02650 
02651     invalidateActions();
02652     updateAppCaption();
02653     return true;
02654 }
02655 
02656 void
02657 KexiMainWindowImpl::slotProjectOpen()
02658 {
02659     KexiStartupDialog dlg(
02660         KexiStartupDialog::OpenExisting, 0, Kexi::connset(), Kexi::recentProjects(),
02661         this, "KexiOpenDialog");
02662 
02663     if (dlg.exec()!=QDialog::Accepted)
02664         return;
02665 
02666     openProject(dlg.selectedFileName(), dlg.selectedExistingConnection());
02667 }
02668 
02669 tristate KexiMainWindowImpl::openProject(const QString& aFileName, 
02670     const QString& fileNameForConnectionData, const QString& dbName)
02671 {
02672     if (d->prj)
02673         return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName);
02674 
02675     KexiDB::ConnectionData *cdata = 0;
02676     if (!fileNameForConnectionData.isEmpty()) {
02677         cdata = Kexi::connset().connectionDataForFileName( fileNameForConnectionData );
02678         if (!cdata) {
02679             kdWarning() << "KexiMainWindowImpl::openProject() cdata?" << endl;
02680             return false;
02681         }
02682     }
02683     return openProject(aFileName, cdata, dbName);
02684 }
02685 
02686 tristate KexiMainWindowImpl::openProject(const QString& aFileName, 
02687     KexiDB::ConnectionData *cdata, const QString& dbName,
02688     const QValueList<KexiProjectData::ObjectInfo>& autoopenObjects)
02689 {
02690     if (d->prj) {
02691         return openProjectInExternalKexiInstance(aFileName, cdata, dbName);
02692     }
02693 
02694     KexiProjectData* projectData = 0;
02695     bool deleteAfterOpen = false;
02696     if (cdata) {
02697         //server-based project
02698         if (dbName.isEmpty()) {//no database name given, ask user
02699             bool cancel;
02700             projectData = Kexi::startupHandler().selectProject( cdata, cancel, this );
02701             if (cancel)
02702                 return cancelled;
02703         }
02704         else {
02706             projectData = new KexiProjectData( *cdata, dbName );
02707             deleteAfterOpen = true;
02708         }
02709     }
02710     else {
02711 //      QString selFile = dlg.selectedExistingFile();
02712         if (aFileName.isEmpty()) {
02713             kdWarning() << "KexiMainWindowImpl::openProject(): aFileName.isEmpty()" << endl;
02714             return false;
02715         }
02716         //file-based project
02717         kdDebug() << "Project File: " << aFileName << endl;
02718         KexiDB::ConnectionData cdata;
02719         cdata.setFileName( aFileName );
02720 //          cdata.driverName = KexiStartupHandler::detectDriverForFile( cdata.driverName, fileName, this );
02721         QString detectedDriverName;
02722         KexiStartupData::Import importActionData;
02723         const tristate res = KexiStartupHandler::detectActionForFile( 
02724             importActionData, detectedDriverName, cdata.driverName, aFileName, this );
02725         if (true != res)
02726             return res;
02727 
02728         if (importActionData) { //importing requested
02729             return showProjectMigrationWizard( importActionData.mimeType, importActionData.fileName );
02730         }
02731         cdata.driverName = detectedDriverName;
02732 
02733         if (cdata.driverName.isEmpty())
02734             return false;
02735 
02736         //opening requested
02737         projectData = new KexiProjectData(cdata, aFileName);
02738         deleteAfterOpen = true;
02739     }
02740     if (!projectData)
02741         return false;
02742     projectData->autoopenObjects = autoopenObjects;
02743     const tristate res = openProject(*projectData);
02744     if (deleteAfterOpen) //projectData object has been copied
02745         delete projectData;
02746     return res;
02747 }
02748 
02749 tristate KexiMainWindowImpl::openProjectInExternalKexiInstance(const QString& aFileName, 
02750     KexiDB::ConnectionData *cdata, const QString& dbName)
02751 {
02752     QString fileNameForConnectionData;
02753     if (aFileName.isEmpty()) { //try .kexic file
02754         if (cdata)
02755             fileNameForConnectionData = Kexi::connset().fileNameForConnectionData(cdata);
02756     }
02757     return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName);
02758 }
02759 
02760 tristate KexiMainWindowImpl::openProjectInExternalKexiInstance(const QString& aFileName, 
02761     const QString& fileNameForConnectionData, const QString& dbName)
02762 {
02763     QString fileName(aFileName);
02764     QStringList args;
02765     args << qApp->applicationFilePath();
02766     // open a file-based project or a server connection provided as a .kexic file
02767     // (we have no other simple way to provide the startup data to a new process)
02768     if (fileName.isEmpty()) { //try .kexic file
02769         if (!fileNameForConnectionData.isEmpty())
02770             args << "--skip-conn-dialog"; //user does not expect conn. dialog to be shown here
02771 
02772         if (dbName.isEmpty()) { //use 'kexi --skip-conn-dialog file.kexic'
02773             fileName = fileNameForConnectionData;
02774         }
02775         else { //use 'kexi --skip-conn-dialog --connection file.kexic dbName'
02776             args << "--connection" << fileNameForConnectionData;
02777             fileName = dbName;
02778         }
02779     }
02780     if (fileName.isEmpty()) {
02781         kdWarning() << "KexiMainWindowImpl::openProjectInExternalKexiInstance() fileName?" << endl;
02782         return false;
02783     }
02785     args << fileName;
02786     QProcess proc(args, this, "process");
02787     proc.setWorkingDirectory( QFileInfo(fileName).dir(true) );
02788     const bool ok = proc.start();
02789     if (!ok) {
02790         d->showStartProcessMsg(args);
02791     }
02792     return ok;
02793 }
02794 
02795 void
02796 KexiMainWindowImpl::slotProjectOpenRecentAboutToShow()
02797 {
02798     /*
02799     //setup
02800     KPopupMenu *popup = d->action_open_recent->popupMenu();
02801     const int cnt = popup->count();
02802     //remove older
02803     for (int i = 0; i<cnt; i++) {
02804         int id = popup->idAt(0);
02805         if (id==d->action_open_recent_more_id)
02806             break;
02807         if (id>=0) {
02808             popup->removeItem(id);
02809         }
02810     }
02811     //insert current items
02812     int cur_id = 0, cur_idx = 0;
02813     //TODO:
02814     cur_id = popup->insertItem("My example project 1", ++cur_id, cur_idx++);
02815     cur_id = popup->insertItem("My example project 2", ++cur_id, cur_idx++);
02816     cur_id = popup->insertItem("My example project 3", ++cur_id, cur_idx++);
02817     */
02818 
02819     //show recent databases
02820     KPopupMenu *popup = d->action_open_recent->popupMenu();
02821     popup->clear();
02822 #if 0
02823     d->action_open_recent_projects_title_id = popup->insertTitle(i18n("Recently Opened Databases"));
02824 #endif
02825 //  int action_open_recent_projects_title_index = popup->indexOf(d->action_open_recent_projects_title_id);
02826 //  int count = popup->count();
02827 //  int action_open_recent_connections_title_index = popup->indexOf(d->action_open_recent_connections_title_id);
02828 //  for (int i=action_open_recent_projects_title_index+1; 
02829 //      i<action_open_recent_connections_title_index; i++)
02830 //  {
02831 //      popup->removeItemAt(action_open_recent_projects_title_index+1);
02832 //  }
02833 
02834 //  int cur_idx = action_open_recent_projects_title_index+1;
02835     popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 1");
02836     popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 2");
02837     popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 3");
02838 
02839 #if 0
02840     //show recent connections
02841     d->action_open_recent_connections_title_id = 
02842         d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Connected Database Servers"));
02843     
02844 //  cur_idx = popup->indexOf(d->action_open_recent_connections_title_id) + 1;
02845 //  for (int i=cur_idx; i<count; i++) {
02846 //      popup->removeItemAt(cur_idx);
02847 //  }
02848     popup->insertItem(SmallIconSet("socket"), "My connection 1");
02849     popup->insertItem(SmallIconSet("socket"), "My connection 2");
02850     popup->insertItem(SmallIconSet("socket"), "My connection 3");
02851     popup->insertItem(SmallIconSet("socket"), "My connection 4");
02852 #endif
02853 }
02854 
02855 void
02856 KexiMainWindowImpl::slotProjectOpenRecent(int id)
02857 {
02858     if (id<0) // || id==d->action_open_recent_more_id)
02859         return;
02860     kdDebug() << "KexiMainWindowImpl::slotProjectOpenRecent("<<id<<")"<<endl;
02861 }
02862 
02863 void
02864 KexiMainWindowImpl::slotProjectOpenRecentMore()
02865 {
02866     KEXI_UNFINISHED(i18n("Open Recent"));
02867 }
02868 
02869 void
02870 KexiMainWindowImpl::slotProjectSave()
02871 {
02872     if (!d->curDialog)
02873         return;
02874     saveObject( d->curDialog );
02875     updateAppCaption();
02876     invalidateActions();
02877 }
02878 
02879 void
02880 KexiMainWindowImpl::slotProjectSaveAs()
02881 {
02882     KEXI_UNFINISHED(i18n("Save object as"));
02883 }
02884 
02885 void
02886 KexiMainWindowImpl::slotProjectPrint()
02887 {
02888     if (d->curDialog && d->curDialog->partItem())
02889         printItem(d->curDialog->partItem());
02890 }
02891 
02892 void
02893 KexiMainWindowImpl::slotProjectPrintPreview()
02894 {
02895     if (d->curDialog && d->curDialog->partItem())
02896         printPreviewForItem(d->curDialog->partItem());
02897 }
02898 
02899 void
02900 KexiMainWindowImpl::slotProjectPageSetup()
02901 {
02902     if (d->curDialog && d->curDialog->partItem())
02903         showPageSetupForItem(d->curDialog->partItem());
02904 }
02905 
02906 void KexiMainWindowImpl::slotProjectExportDataTable()
02907 {
02908     if (d->curDialog && d->curDialog->partItem())
02909         exportItemAsDataTable(d->curDialog->partItem());
02910 }
02911 
02912 void
02913 KexiMainWindowImpl::slotProjectProperties()
02914 {
02915     //TODO: load the implementation not the ui :)
02916 //  ProjectSettingsUI u(this);
02917 //  u.exec();
02918 }
02919 
02920 void
02921 KexiMainWindowImpl::slotProjectClose()
02922 {
02923     closeProject();
02924 }
02925 
02926 void KexiMainWindowImpl::slotProjectRelations()
02927 {
02928     if (!d->prj)
02929         return;
02930     KexiDialogBase *d = KexiInternalPart::createKexiDialogInstance("relation", this, this);
02931     activateWindow(d);
02932 }
02933 
02934 void KexiMainWindowImpl::slotImportFile()
02935 {
02936     KEXI_UNFINISHED("Import: " + i18n("From File..."));
02937 }
02938 
02939 void KexiMainWindowImpl::slotImportServer()
02940 {
02941     KEXI_UNFINISHED("Import: " + i18n("From Server..."));
02942 }
02943 
02944 void
02945 KexiMainWindowImpl::slotProjectQuit()
02946 {
02947     if (~ closeProject())
02948         return;
02949     close();
02950 }
02951 
02952 void KexiMainWindowImpl::slotViewNavigator()
02953 {
02954     if (!d->nav || !d->navToolWindow)
02955         return;
02956     if (!d->nav->isVisible())
02957         makeWidgetDockVisible(d->nav);
02958 //      makeDockVisible(dynamic_cast<KDockWidget*>(d->navToolWindow->wrapperWidget()));
02959 //      d->navToolWindow->wrapperWidget()->show();
02960 //      d->navToolWindow->show(KDockWidget::DockLeft, getMainDockWidget());
02961 
02962     d->navToolWindow->wrapperWidget()->raise();
02963 //
02964     d->block_KMdiMainFrm_eventFilter=true;
02965         d->nav->setFocus();
02966     d->block_KMdiMainFrm_eventFilter=false;
02967 }
02968 
02969 void KexiMainWindowImpl::slotViewMainArea()
02970 {
02971     if (d->curDialog)
02972         d->curDialog->setFocus();
02973 }
02974 
02975 void KexiMainWindowImpl::slotViewPropertyEditor()
02976 {
02977     if (!d->propEditor || !d->propEditorToolWindow)
02978         return;
02979 
02980 //js        d->config->setGroup("MainWindow");
02981 //js        ds->setSeparatorPos(d->config->readNumEntry("RightDockPosition", 80/* % */), true);
02982 
02983     if (!d->propEditorTabWidget->isVisible())
02984         makeWidgetDockVisible(d->propEditorTabWidget);
02985 
02986 
02987     d->propEditorToolWindow->wrapperWidget()->raise();
02988 
02989     d->block_KMdiMainFrm_eventFilter=true;
02990     if (d->propEditorTabWidget->currentPage())
02991         d->propEditorTabWidget->currentPage()->setFocus();
02992     d->block_KMdiMainFrm_eventFilter=false;
02993 
02994 /*#if defined(KDOCKWIDGET_P)
02995         KDockWidget *dw = (KDockWidget *)d->propEditor->parentWidget();
02996         KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
02997         ds->setSeparatorPos(80,true);//d->config->readNumEntry("RightDockPosition", 80), true);
02998 #endif*/
02999 }
03000 
03001 bool KexiMainWindowImpl::switchToViewMode(int viewMode)
03002 {
03003     if (!d->curDialog) {
03004         d->toggleLastCheckedMode();
03005         return false;
03006     }
03007     if (!d->curDialog->supportsViewMode( viewMode )) {
03008         showErrorMessage(i18n("Selected view is not supported for \"%1\" object.")
03009             .arg(d->curDialog->partItem()->name()),
03010         i18n("Selected view (%1) is not supported by this object type (%2).")
03011             .arg(Kexi::nameForViewMode(viewMode))
03012             .arg(d->curDialog->part()->instanceCaption()) );
03013         d->toggleLastCheckedMode();
03014         return false;
03015     }
03016     int prevViewMode = d->curDialog->currentViewMode();
03017     updateCustomPropertyPanelTabs(d->curDialog->part(), prevViewMode,
03018         d->curDialog->part(), viewMode );
03019     tristate res = d->curDialog->switchToViewMode( viewMode );
03020     if (!res) {
03021         updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
03022         showErrorMessage(i18n("Switching to other view failed (%1).").arg(Kexi::nameForViewMode(viewMode)),
03023             d->curDialog);
03024         d->toggleLastCheckedMode();
03025         return false;
03026     }
03027     if (~res) {
03028         updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
03029         d->toggleLastCheckedMode();
03030         return false;
03031     }
03032 
03033     //view changed: switch to this view's gui client
03034     KXMLGUIClient *viewClient=d->curDialog->guiClient();
03035     updateDialogViewGUIClient(viewClient);
03036     if (d->curDialogViewGUIClient && !viewClient)
03037         guiFactory()->removeClient(d->curDialogViewGUIClient);
03038     d->curDialogViewGUIClient=viewClient; //remember
03039 
03040     d->updatePropEditorVisibility(viewMode);
03041     invalidateProjectWideActions();
03042     invalidateSharedActions();
03043     d->updateFindDialogContents();
03044     return true;
03045 }
03046 
03047 
03048 void KexiMainWindowImpl::slotViewDataMode()
03049 {
03050     switchToViewMode(Kexi::DataViewMode);
03051 }
03052 
03053 void KexiMainWindowImpl::slotViewDesignMode()
03054 {
03055     switchToViewMode(Kexi::DesignViewMode);
03056 }
03057 
03058 void KexiMainWindowImpl::slotViewTextMode()
03059 {
03060     switchToViewMode(Kexi::TextViewMode);
03061 }
03062 
03063 void KexiMainWindowImpl::closeWindow(KMdiChildView *pWnd, bool layoutTaskBar)
03064 {
03065     if (d->insideCloseDialog && dynamic_cast<KexiDialogBase *>(pWnd)) {
03066         d->windowsToClose.append(dynamic_cast<KexiDialogBase *>(pWnd));
03067         return;
03068     }
03069     /*moved to closeDialog()
03070     if (pWnd == d->curDialog && !pWnd->isAttached()) {
03071         if (d->propEditor) {
03072             // ah, closing detached window - better switch off property buffer right now...
03073             d->propBuffer = 0;
03074             d->propEditor->editor()->setBuffer( 0, false );
03075         }
03076     }
03077     */
03078     closeDialog(dynamic_cast<KexiDialogBase *>(pWnd), layoutTaskBar);
03079 }
03080 
03081 tristate KexiMainWindowImpl::getNewObjectInfo(
03082     KexiPart::Item *partItem, KexiPart::Part *part,
03083     bool& allowOverwriting, const QString& messageWhenAskingForName )
03084 {
03085     //data was never saved in the past -we need to create a new object at the backend
03086     KexiPart::Info *info = part->info();
03087 #ifdef KEXI_ADD_CUSTOM_OBJECT_CREATION
03088 # include "keximainwindowimpl_customobjcreation.h"
03089 #endif
03090     if (!d->nameDialog) {
03091         d->nameDialog = new KexiNameDialog(
03092             messageWhenAskingForName, this, "nameDialog");
03093         //check if that name is allowed
03094         d->nameDialog->widget()->addNameSubvalidator(
03095             new KexiDB::ObjectNameValidator(project()->dbConnection()->driver(), 0, "sub"));
03096     }
03097     else {
03098         d->nameDialog->widget()->setMessageText( messageWhenAskingForName );
03099     }
03100     d->nameDialog->widget()->setCaptionText(partItem->caption());
03101     d->nameDialog->widget()->setNameText(partItem->name());
03102     d->nameDialog->setCaption(i18n("Save Object As"));
03103     d->nameDialog->setDialogIcon( DesktopIcon( info->itemIcon(), KIcon::SizeMedium ) );
03104     allowOverwriting = false;
03105     bool found;
03106     do {
03107         if (d->nameDialog->exec()!=QDialog::Accepted)
03108             return cancelled;
03109         //check if that name already exists
03110         KexiDB::SchemaData tmp_sdata;
03111         tristate result = project()->dbConnection()->loadObjectSchemaData(
03112             info->projectPartID(),
03113             d->nameDialog->widget()->nameText(), tmp_sdata );
03114         if (!result)
03115             return false;
03116         found = result==true;
03117         if (found) {
03118             if (allowOverwriting) {
03119                 int res = KMessageBox::warningYesNoCancel(this,
03120                     "<p>"+part->i18nMessage("Object \"%1\" already exists.", 0)
03121                         .arg(d->nameDialog->widget()->nameText())
03122                     +"</p><p>"+i18n("Do you want to replace it?")+"</p>", 0,
03123                     KGuiItem(i18n("&Replace"), "button_yes"),
03124                     KGuiItem(i18n("&Choose Other Name...")),
03125                     QString::null, KMessageBox::Notify|KMessageBox::Dangerous);
03126                 if (res == KMessageBox::No)
03127                     continue;
03128                 else if (res == KMessageBox::Cancel)
03129                     return cancelled;
03130                 else {//yes
03131                     allowOverwriting = true;
03132                     break;
03133                 }
03134             }
03135             else {
03136                 KMessageBox::information(this,
03137                     "<p>"+part->i18nMessage("Object \"%1\" already exists.", 0)
03138                         .arg(d->nameDialog->widget()->nameText())
03139                     +"</p><p>"+i18n("Please choose other name.")+"</p>");
03140 //              " For example: Table \"my_table\" already exists" ,
03141 //              "%1 \"%2\" already exists.\nPlease choose other name.")
03142 //              .arg(dlg->part()->instanceName()).arg(d->nameDialog->widget()->nameText()));
03143                 continue;
03144             }
03145         }
03146     }
03147     while (found);
03148 
03149     //update name and caption
03150     partItem->setName( d->nameDialog->widget()->nameText() );
03151     partItem->setCaption( d->nameDialog->widget()->captionText() );
03152     return true;
03153 }
03154 
03155 tristate KexiMainWindowImpl::saveObject( KexiDialogBase *dlg, const QString& messageWhenAskingForName,
03156     bool dontAsk)
03157 {
03158     tristate res;
03159     if (!dlg->neverSaved()) {
03160         //data was saved in the past -just save again
03161         res = dlg->storeData(dontAsk);
03162         if (!res)
03163             showErrorMessage(i18n("Saving \"%1\" object failed.").arg(dlg->partItem()->name()),
03164                 d->curDialog);
03165         return res;
03166     }
03167 
03168     const int oldItemID = dlg->partItem()->identifier();
03169 
03170     bool allowOverwriting = false;
03171     res = getNewObjectInfo( dlg->partItem(), dlg->part(), allowOverwriting,
03172         messageWhenAskingForName );
03173     if (res != true)
03174         return res;
03175 
03176     res = dlg->storeNewData();
03177     if (~res)
03178         return cancelled;
03179     if (!res) {
03180         showErrorMessage(i18n("Saving new \"%1\" object failed.").arg(dlg->partItem()->name()),
03181             d->curDialog);
03182         return false;
03183     }
03184 
03185     //update navigator
03186 //this is alreday done in KexiProject::addStoredItem(): d->nav->addItem(dlg->partItem());
03187     //item id changed to final one: update association in dialogs' dictionary
03188 //  d->dialogs.take(oldItemID);
03189     d->updateDialogId(dlg, oldItemID);
03190     invalidateProjectWideActions();
03191     return true;
03192 }
03193 
03194 tristate KexiMainWindowImpl::closeDialog(KexiDialogBase *dlg)
03195 {
03196     return closeDialog(dlg, true);
03197 }
03198 
03199 tristate KexiMainWindowImpl::closeDialog(KexiDialogBase *dlg, bool layoutTaskBar, bool doNotSaveChanges)
03200 {
03201     if (!dlg) 
03202         return true;
03203     if (d->insideCloseDialog)
03204         return true;
03205 
03206 #ifndef KEXI_NO_PENDING_DIALOGS
03207     d->addItemToPendingDialogs(dlg->partItem(), Private::DialogClosingJob);
03208 #endif
03209 
03210     d->insideCloseDialog = true;
03211 
03212     if (dlg == d->curDialog && !dlg->isAttached()) {
03213         if (d->propEditor) {
03214             // ah, closing detached window - better switch off property buffer right now...
03215             d->propBuffer = 0;
03216             d->propEditor->editor()->changeSet( 0, false );
03217         }
03218     }
03219 
03220     bool remove_on_closing = dlg->partItem() ? dlg->partItem()->neverSaved() : false;
03221     if (dlg->dirty() && !d->forceDialogClosing && !doNotSaveChanges) {
03222         //more accurate tool tips and what's this
03223         KGuiItem saveChanges( KStdGuiItem::save() ); 
03224         saveChanges.setToolTip(i18n("Save changes"));
03225         saveChanges.setWhatsThis(
03226             i18n( "Pressing this button will save all recent changes made in \"%1\" object." )
03227             .arg(dlg->partItem()->name()) );
03228         KGuiItem discardChanges( KStdGuiItem::discard() );
03229         discardChanges.setWhatsThis(
03230             i18n( "Pressing this button will discard all recent changes made in \"%1\" object." )
03231             .arg(dlg->partItem()->name()) );
03232 
03233         //dialog's data is dirty:
03234         //--adidional message, e.g. table designer will return 
03235         //  "Note: This table is already filled with data which will be removed."
03236         //  if the dlg is in design view mode.
03237         QString additionalMessage = dlg->part()->i18nMessage(
03238             ":additional message before saving design", dlg);
03239         if (additionalMessage.startsWith(":"))
03240             additionalMessage = QString::null;
03241         if (!additionalMessage.isEmpty())
03242             additionalMessage = "<p>"+additionalMessage+"</p>";
03243 
03244         const int questionRes = KMessageBox::warningYesNoCancel( this,
03245             "<p>"+dlg->part()->i18nMessage("Design of object \"%1\" has been modified.", dlg)
03246             .arg(dlg->partItem()->name())+"</p><p>"+i18n("Do you want to save changes?")+"</p>"
03247             + additionalMessage /*may be empty*/,
03248             QString::null,
03249             saveChanges,
03250             discardChanges);
03251         if (questionRes==KMessageBox::Cancel) {
03252 #ifndef KEXI_NO_PENDING_DIALOGS
03253             d->removePendingDialog(dlg->id());
03254 #endif
03255             d->insideCloseDialog = false;
03256             d->windowsToClose.clear(); //give up with 'close all'
03257             return cancelled;
03258         }
03259         if (questionRes==KMessageBox::Yes) {
03260             //save it
03261 //          if (!dlg->storeData())
03262             tristate res = saveObject( dlg, QString::null, true /*dontAsk*/ );
03263             if (!res || ~res) {
03264 //js:TODO show error info; (retry/ignore/cancel)
03265 #ifndef KEXI_NO_PENDING_DIALOGS
03266                 d->removePendingDialog(dlg->id());
03267 #endif
03268                 d->insideCloseDialog = false;
03269                 d->windowsToClose.clear(); //give up with 'close all'
03270                 return res;
03271             }
03272             remove_on_closing = false;
03273         }
03274     }
03275 
03276     const int dlg_id = dlg->id(); //remember now, because removeObject() can destruct partitem object
03277 
03278     if (remove_on_closing) {
03279         //we won't save this object, and it was never saved -remove it
03280         if (!removeObject( dlg->partItem(), true )) {
03281 #ifndef KEXI_NO_PENDING_DIALOGS
03282             d->removePendingDialog(dlg->id());
03283 #endif
03284             //msg?
03285             //TODO: ask if we'd continue and return true/false
03286             d->insideCloseDialog = false;
03287             d->windowsToClose.clear(); //give up with 'close all'
03288             return false;
03289         }
03290     }
03291     else {
03292         //not dirty now
03293         if(d->nav)
03294             d->nav->updateItemName( *dlg->partItem(), false );
03295     }
03296 
03297     d->removeDialog(dlg_id); //don't remove -KMDI will do that
03298     //also remove from 'print setup dialogs' cache, if needed
03299     int printedObjectID = 0;
03300     if (d->pageSetupDialogItemID2dataItemID_map.contains(dlg_id))
03301         printedObjectID = d->pageSetupDialogItemID2dataItemID_map[ dlg_id ];
03302     d->pageSetupDialogs.take(printedObjectID);
03303 
03304     KXMLGUIClient *client = dlg->commonGUIClient();
03305     KXMLGUIClient *viewClient = dlg->guiClient();
03306     if (d->curDialogGUIClient==client) {
03307         d->curDialogGUIClient=0;
03308     }
03309     if (d->curDialogViewGUIClient==viewClient) {
03310         d->curDialogViewGUIClient=0;
03311     }
03312     if (client) {
03313         //sanity: ouch, it is not removed yet? - do it now
03314         if (d->closedDialogGUIClient && d->closedDialogGUIClient!=client)
03315             guiFactory()->removeClient(d->closedDialogGUIClient);
03316         if (d->openedDialogsCount()==0) {//now there is no dialogs - remove client RIGHT NOW!
03317             d->closedDialogGUIClient=0;
03318             guiFactory()->removeClient(client);
03319         }
03320         else {
03321             //remember this - and MAYBE remove later, if needed
03322             d->closedDialogGUIClient=client;
03323         }
03324     }
03325     if (viewClient) {
03326         //sanity: ouch, it is not removed yet? - do it now
03327         if (d->closedDialogViewGUIClient && d->closedDialogViewGUIClient!=viewClient)
03328             guiFactory()->removeClient(d->closedDialogViewGUIClient);
03329         if (d->openedDialogsCount()==0) {//now there is no dialogs - remove client RIGHT NOW!
03330             d->closedDialogViewGUIClient=0;
03331             guiFactory()->removeClient(viewClient);
03332         }
03333         else {
03334             //remember this - and MAYBE remove later, if needed
03335             d->closedDialogViewGUIClient=viewClient;
03336         }
03337     }
03338 
03339     const bool isInMaximizedChildFrmMode = this->isInMaximizedChildFrmMode();
03340 
03341     KMdiMainFrm::closeWindow(dlg, layoutTaskBar);
03342 
03343     //focus navigator if nothing else available
03344     if (d->openedDialogsCount()==0) {
03345         d->maximizeFirstOpenedChildFrm = isInMaximizedChildFrmMode;
03346         if (d->nav)
03347             d->nav->setFocus();
03348         d->updatePropEditorVisibility(0);
03349     }
03350 
03351     invalidateActions();
03352     d->insideCloseDialog = false;
03353     if (!d->windowsToClose.isEmpty()) //continue 'close all'
03354         closeDialog(d->windowsToClose.take(0), true);
03355 
03356 #ifndef KEXI_NO_PENDING_DIALOGS
03357     d->removePendingDialog( dlg_id );
03358 
03359     //perform pending global action that was suspended:
03360     if (!d->pendingDialogsExist()) {
03361         d->executeActionWhenPendingJobsAreFinished();
03362     }
03363 #endif
03364     return true;
03365 }
03366 
03367 void KexiMainWindowImpl::detachWindow(KMdiChildView *pWnd,bool bShow)
03368 {
03369     KMdiMainFrm::detachWindow(pWnd,bShow);
03370     // update icon - from small to large
03371     pWnd->setIcon( DesktopIcon( static_cast<KexiDialogBase *>(pWnd)->itemIcon() ) );
03372 //  pWnd->setIcon( DesktopIcon( static_cast<KexiDialogBase *>(pWnd)->part()->info()->itemIcon() ) );
03373     if (dynamic_cast<KexiDialogBase*>(pWnd))
03374         dynamic_cast<KexiDialogBase*>(pWnd)->sendDetachedStateToCurrentView();
03375 }
03376 
03377 void KexiMainWindowImpl::attachWindow(KMdiChildView *pWnd, bool /*bShow*/, bool bAutomaticResize)
03378 {
03379 //  if (bAutomaticResize || w->size().isEmpty() || (w->size() == QSize(1,1))) {
03380     KMdiMainFrm::attachWindow(pWnd,true,bAutomaticResize);
03381     //for dialogs in normal state: decrease dialog's height if it exceeds area contents
03382     if (pWnd->mdiParent()->state() == KMdiChildFrm::Normal
03383         && pWnd->geometry().bottom() > pWnd->mdiParent()->mdiAreaContentsRect().bottom())
03384     {
03385         QRect r = pWnd->geometry();
03386         r.setBottom( pWnd->mdiParent()->mdiAreaContentsRect().bottom() - 5 );
03387         pWnd->setGeometry( r );
03388     }
03389     // update icon - from large to small
03390     pWnd->mdiParent()->setIcon( SmallIcon( static_cast<KexiDialogBase *>(pWnd)->itemIcon() ) );
03391     if (dynamic_cast<KexiDialogBase*>(pWnd))
03392         dynamic_cast<KexiDialogBase*>(pWnd)->sendAttachedStateToCurrentView();
03393 }
03394 
03395 QWidget* KexiMainWindowImpl::findWindow(QWidget *w)
03396 {
03397     while (w && !acceptsSharedActions(w))
03398         w = w->parentWidget();
03399     return w;
03400 }
03401 
03402 bool KexiMainWindowImpl::acceptsSharedActions(QObject *w)
03403 {
03404     return w->inherits("KexiDialogBase") || w->inherits("KexiViewBase");
03405 }
03406 
03407 bool KexiMainWindowImpl::eventFilter( QObject *obj, QEvent * e )
03408 {
03409     //KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name()<<endl;
03410     if (e->type()==QEvent::KeyPress) {
03411         KexiVDebug << "KEY EVENT " << QString::number(static_cast<QKeyEvent*>(e)->key(), 16) << endl;
03412         KexiVDebug << endl;
03413     }
03414     if (e->type()==QEvent::AccelOverride) {
03415         //KexiVDebug << "AccelOverride EVENT " << static_cast<QKeyEvent*>(e)->key() << " " << static_cast<QKeyEvent*>(e)->state() == ControlButton << endl;
03416 
03417         //avoid sending CTRL+Tab key twice for tabbed/ideal mode, epecially for win32
03418         if (static_cast<QKeyEvent*>(e)->key()==Qt::Key_Tab && static_cast<QKeyEvent*>(e)->state() == ControlButton) {
03419             if (d->action_window_next->shortcut().keyCodeQt()==Qt::Key_Tab+Qt::CTRL && d->action_window_next->shortcut().count()==1
03420                 && (mdiMode()==KMdi::TabPageMode || mdiMode()==KMdi::IDEAlMode))
03421             {
03422                 static_cast<QKeyEvent*>(e)->accept();
03423             }
03424         }
03425     }
03426     if (e->type()==QEvent::Close) {
03427         KexiVDebug << "Close EVENT" << endl;
03428     }
03429     if (e->type()==QEvent::Resize) {
03430         KexiVDebug << "Resize EVENT" << endl;
03431     }
03432     if (e->type()==QEvent::ShowMaximized) {
03433         KexiVDebug << "ShowMaximized EVENT" << endl;
03434     }
03435 
03436 /*  if (obj==d->propEditor) {
03437         if (e->type()==QEvent::Resize) {
03438             d->updatePropEditorDockWidthInfo();
03439         }
03440     }*/
03441 
03442     QWidget *focus_w = 0;
03443     if (obj->inherits("QPopupMenu")) {
03444         /* Fixes for popup menus behaviour:
03445          For hiding/showing: focus previously (d->focus_before_popup)
03446          focused window, if known, otherwise focus currently focused one.
03447          And: just invalidate actions.
03448         */
03449         if (e->type()==QEvent::Hide || e->type()==QEvent::Show) {
03450             KexiVDebug << e->type() << endl;
03451             focus_w = focusWindow();
03452             if (!d->focus_before_popup.isNull()) {
03453                 d->focus_before_popup->setFocus();
03454                 d->focus_before_popup=0;
03455                 invalidateSharedActions();
03456             } else {
03457                 if (focus_w) {
03458                     focus_w->setFocus();
03459                     invalidateSharedActions();
03460                 }
03461             }
03462         }
03463         return false;
03464     }
03465 
03467     if (e->type()==QEvent::MouseButtonPress) {
03468         QWidget *w = findWindow(static_cast<QWidget*>(obj));
03469         KexiVDebug << "MouseButtonPress EVENT " <<  (w ? w->name() : 0) << endl;
03470         if (w) {
03471             w->setFocus();
03472             invalidateSharedActions(d->curDialog);
03473         }
03474     }
03475     QWidget *w = findWindow(static_cast<QWidget*>(obj));
03476     if (e->type()==QEvent::FocusIn) {
03477         focus_w = focusWindow();
03478         KexiVDebug << "Focus EVENT" << endl;
03479         KexiVDebug << (focus_w ? focus_w->name() : "" )  << endl;
03480         KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name() <<endl;
03481 #ifdef KEXI_STATUSBAR_DEBUG
03482         QWidget *focus_widget = focus_w ? focus_w->focusWidget() : 0;
03483         d->statusBar->setStatus(QString("FOCUS VIEW: %1 %2, FOCUS WIDGET: %3 %4")
03484             .arg(focus_w ? focus_w->className() : "").arg(focus_w ? focus_w->name() : "")
03485             .arg(focus_widget ? focus_widget->className() : "").arg(focus_widget ? focus_widget->name() : "")
03486             );
03487 #endif
03488     }
03489     else if (e->type()==QEvent::FocusOut) {
03490         focus_w = focusWindow();
03491         KexiVDebug << "Focus OUT EVENT" << endl;
03492         KexiVDebug << (focus_w ? focus_w->name() : "" )  << endl;
03493         KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name() <<endl;
03494 #ifdef KEXI_STATUSBAR_DEBUG
03495         QWidget *focus_widget = focus_w ? focus_w->focusWidget() : 0;
03496         d->statusBar->setStatus(QString("FOCUS VIEW: %1 %2, FOCUS WIDGET: %3 %4")
03497             .arg(focus_w ? focus_w->className() : "").arg(focus_w ? focus_w->name() : "")
03498             .arg(focus_widget ? focus_widget->className() : "").arg(focus_widget ? focus_widget->name() : "")
03499             );
03500 #endif
03501     }
03502     if (e->type()==QEvent::WindowActivate) {
03503         KexiVDebug << "WindowActivate EVENT" << endl;
03504         KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name()<<endl;
03505     }
03506 #if 0
03507     if (e->type()==QEvent::FocusIn) {
03508         if (focus_w) {
03509 //          if (d->actionProxies[ w ])
03510 //          if (d->actionProxies[ focus_w ]) {
03511             if (actionProxyFor( focus_w )) {
03512 //              invalidateSharedActions();
03513             }
03514             else {
03515 /*          QObject* o = focusWidget();
03516             while (o && !o->inherits("KexiDialogBase") && !o->inherits("KexiDockBase"))
03517                 o = o->parent();*/
03518 //js                invalidateSharedActions(focus_w);
03519             }
03520         }
03521 //      /*|| e->type()==QEvent::FocusOut*/) && /*(!obj->inherits("KexiDialogBase")) &&*/ d->actionProxies[ obj ]) {
03522 //      invalidateSharedActions();
03523     }
03524     if (e->type()==QEvent::FocusOut && focus_w && focus_w==d->curDialog && actionProxyFor( obj )) {
03525         invalidateSharedActions(d->curDialog);
03526     }
03527 #endif
03528 
03529     if (!d->focus_before_popup.isNull() && e->type()==QEvent::FocusOut && obj->inherits("KMenuBar")) {
03530         //d->nav->setFocus();
03531         d->focus_before_popup->setFocus();
03532         d->focus_before_popup=0;
03533         invalidateSharedActions(d->curDialog);
03534         return true;
03535     }
03536 
03537     //remember currently focued window invalidate act.
03538     if (e->type()==QEvent::FocusOut) {
03539         if (static_cast<QFocusEvent*>(e)->reason()==QFocusEvent::Popup) {
03540             if (KexiUtils::hasParent(d->curDialog, focus_w)) {
03541                 invalidateSharedActions(d->curDialog);
03542                 d->focus_before_popup=d->curDialog;
03543             }
03544             else {
03545 //not needed???         invalidateSharedActions(focus_w);
03546                 d->focus_before_popup=focus_w;
03547             }
03548         }
03549     }
03550 
03551     //keep focus in main window:
03552     if (w && w==d->nav) {
03553 //      kdDebug() << "NAV" << endl;
03554         if (e->type()==QEvent::FocusIn) {
03555             return true;
03556         } else if (e->type()==QEvent::WindowActivate && w==d->focus_before_popup) {
03557 //          d->nav->setFocus();
03558             d->focus_before_popup=0;
03559             return true;
03560         } else if (e->type()==QEvent::FocusOut) {
03561             if (static_cast<QFocusEvent*>(e)->reason()==QFocusEvent::Tab) {
03562                 //activate current child:
03563                 if (d->curDialog) {
03564                     d->curDialog->activate();
03565                     return true;
03566                 }
03567             }
03568             else if (static_cast<QFocusEvent*>(e)->reason()==QFocusEvent::Popup) {
03569                 d->focus_before_popup=w;
03570             }
03571             //invalidateSharedActions();
03572         } else if (e->type()==QEvent::Hide) {
03573             setFocus();
03574             return false;
03575         }
03576     }
03577     if (d->block_KMdiMainFrm_eventFilter)//we don't want KMDI to eat our event!
03578         return false;
03579     return KMdiMainFrm::eventFilter(obj,e);//let KMDI do its work
03580 }
03581 
03582 bool KexiMainWindowImpl::openingAllowed(KexiPart::Item* item, int viewMode)
03583 {
03585     if (!userMode())
03586         return true;
03587     KexiPart::Part * part = Kexi::partManager().partForMimeType(item->mimeType());
03588     return part && (part->supportedUserViewModes() & viewMode);
03589 }
03590 
03591 KexiDialogBase *
03592 KexiMainWindowImpl::openObject(const QCString& mimeType, const QString& name, 
03593     int viewMode, bool &openingCancelled, QMap<QString,QString>* staticObjectArgs)
03594 {
03595     KexiPart::Item *item = d->prj->itemForMimeType(mimeType,name);
03596     if (!item)
03597         return 0;
03598     return openObject(item, viewMode, openingCancelled, staticObjectArgs);
03599 }
03600 
03601 KexiDialogBase *
03602 KexiMainWindowImpl::openObject(KexiPart::Item* item, int viewMode, bool &openingCancelled,
03603     QMap<QString,QString>* staticObjectArgs, QString* errorMessage)
03604 {
03605     if (!openingAllowed(item, viewMode)) {
03606         if (errorMessage)
03607             *errorMessage = i18n("opening is not allowed in \"data view/design view/text view\" mode", 
03608                 "opening is not allowed in \"%1\" mode").arg(Kexi::nameForViewMode(viewMode));
03609         openingCancelled = true;
03610         return 0;
03611     }
03612     
03613     if (!d->prj || !item)
03614         return 0;
03615     KexiUtils::WaitCursor wait;
03616 #ifndef KEXI_NO_PENDING_DIALOGS
03617     Private::PendingJobType pendingType;
03618     KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
03619     if (pendingType != Private::NoJob) {
03620         openingCancelled = true;
03621         return 0;
03622     }
03623 #else
03624     KexiDialogBase *dlg = d->openedDialogFor( item );
03625 #endif
03626     openingCancelled = false;
03627 
03628     bool needsUpdateViewGUIClient = true;
03629     if (dlg) {
03630         dlg->activate();
03631         if (viewMode!=dlg->currentViewMode()) {
03632             if (!switchToViewMode(viewMode))
03633                 return 0;
03634         }
03635         needsUpdateViewGUIClient = false;
03636     }
03637     else {
03638         d->updatePropEditorVisibility(viewMode);
03639         KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
03640         //update tabs before opening
03641         updateCustomPropertyPanelTabs(d->curDialog ? d->curDialog->part() : 0,
03642             d->curDialog ? d->curDialog->currentViewMode() : Kexi::NoViewMode,
03643             part, viewMode);
03644 
03645 #ifndef KEXI_NO_PENDING_DIALOGS
03646         d->addItemToPendingDialogs(item, Private::DialogOpeningJob);
03647 #endif
03648         dlg = d->prj->openObject(this, *item, viewMode, staticObjectArgs);
03649     }
03650 
03651     if (!dlg || !activateWindow(dlg)) {
03652 #ifndef KEXI_NO_PENDING_DIALOGS
03653         d->removePendingDialog(item->identifier());
03654 #endif
03655         updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
03656         //js TODO: add error msg...
03657         return 0;
03658     }
03659 
03660     if (needsUpdateViewGUIClient /*&& !userMode()*/) {
03661         //view changed: switch to this view's gui client
03662         KXMLGUIClient *viewClient=dlg->guiClient();
03663         updateDialogViewGUIClient(viewClient);
03664         if (d->curDialogViewGUIClient && !viewClient)
03665             guiFactory()->removeClient(d->curDialogViewGUIClient);
03666         d->curDialogViewGUIClient=viewClient; //remember
03667     }
03668 
03669     invalidateViewModeActions();
03670     if (viewMode!=dlg->currentViewMode())
03671         invalidateSharedActions();
03672 
03673 #ifndef KEXI_NO_PENDING_DIALOGS
03674     d->removePendingDialog( dlg->id() );
03675 
03676     //perform pending global action that was suspended:
03677     if (!d->pendingDialogsExist()) {
03678         d->executeActionWhenPendingJobsAreFinished();
03679     }
03680 #endif
03681     return dlg;
03682 }
03683 
03684 KexiDialogBase *
03685 KexiMainWindowImpl::openObjectFromNavigator(KexiPart::Item* item, int viewMode)
03686 {
03687     bool openingCancelled;
03688     return openObjectFromNavigator(item, viewMode, openingCancelled);
03689 }
03690 
03691 KexiDialogBase *
03692 KexiMainWindowImpl::openObjectFromNavigator(KexiPart::Item* item, int viewMode, 
03693     bool &openingCancelled)
03694 {
03695     if (!openingAllowed(item, viewMode)) {
03696         openingCancelled = true;
03697         return 0;
03698     }
03699     if (!d->prj || !item)
03700         return false;
03701 #ifndef KEXI_NO_PENDING_DIALOGS
03702     Private::PendingJobType pendingType;
03703     KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
03704     if (pendingType!=Private::NoJob) {
03705         openingCancelled = true;
03706         return 0;
03707     }
03708 #else
03709     KexiDialogBase *dlg = d->openedDialogFor( item );
03710 #endif
03711     openingCancelled = false;
03712     if (dlg) {
03713         if (activateWindow(dlg)) {//item->identifier())) {//just activate
03714             invalidateViewModeActions();
03715             return dlg;
03716         }
03717     }
03718     //if DataViewMode is not supported, try Design, then Text mode (currently useful for script part)
03719     KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
03720     if (!part)
03721         return 0;
03722     if (viewMode == Kexi::DataViewMode && !(part->supportedViewModes() & Kexi::DataViewMode)) {
03723         if (part->supportedViewModes() & Kexi::DesignViewMode)
03724             return openObjectFromNavigator( item, Kexi::DesignViewMode, openingCancelled );
03725         else if (part->supportedViewModes() & Kexi::TextViewMode)
03726             return openObjectFromNavigator( item, Kexi::TextViewMode, openingCancelled );
03727     }
03728     //do the same as in openObject()
03729     return openObject(item, viewMode, openingCancelled);
03730 }
03731 
03732 tristate KexiMainWindowImpl::closeObject(KexiPart::Item* item)
03733 {
03734 #ifndef KEXI_NO_PENDING_DIALOGS
03735     Private::PendingJobType pendingType;
03736     KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
03737     if (pendingType == Private::DialogClosingJob)
03738         return true;
03739     else if (pendingType == Private::DialogOpeningJob)
03740         return cancelled;
03741 #else
03742     KexiDialogBase *dlg = d->openedDialogFor( item );
03743 #endif
03744     if (!dlg)
03745         return cancelled;
03746     return closeDialog(dlg);
03747 }
03748 
03749 bool KexiMainWindowImpl::newObject( KexiPart::Info *info, bool& openingCancelled )
03750 {
03751     if (userMode()) {
03752         openingCancelled = true;
03753         return false;
03754     }
03755     openingCancelled = false;
03756     if (!d->prj || !info)
03757         return false;
03758     KexiPart::Part *part = Kexi::partManager().partForMimeType(info->mimeType());
03759     if(!part)
03760         return false;
03761 
03762 #ifdef KEXI_ADD_CUSTOM_OBJECT_CREATION
03763 # include "keximainwindowimpl_customobjcreation.h"
03764 #endif
03765 
03766     KexiPart::Item *it = d->prj->createPartItem(info); //this, *item, viewMode);
03767     if (!it) {
03768         //js: todo: err
03769         return false;
03770     }
03771 
03772     if (!it->neverSaved()) //only add stored objects to the browser
03773         d->nav->addItem(*it);
03774     return openObject(it, Kexi::DesignViewMode, openingCancelled);
03775 }
03776 
03777 tristate KexiMainWindowImpl::removeObject( KexiPart::Item *item, bool dontAsk )
03778 {
03779     if (userMode())
03780         return cancelled;
03781     if (!d->prj || !item)
03782         return false;
03783 
03784     KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
03785     if (!part)
03786         return false;
03787 
03788     if (!dontAsk) {
03789         if (KMessageBox::No == KMessageBox::warningYesNo(this, 
03790             "<p>"+i18n("Do you want to permanently delete:\n"
03791             "%1\n"
03792             "If you click \"Delete\", you will not be able to undo the deletion.")
03793                 .arg( "</p><p>"+part->instanceCaption()+" \""+ item->name() + "\"?</p>" ),
03794             0, KGuiItem(i18n("Delete"), "editdelete"), KStdGuiItem::no()))
03795             return cancelled;
03796     }
03797 
03798     //also close 'print setup' dialog for this item, if any
03799     tristate res;
03800 //  int printedObjectID = 0;
03801 //  if (d->pageSetupDialogItemID2dataItemID_map.contains(item->identifier()))
03802 //      printedObjectID = d->pageSetupDialogItemID2dataItemID_map[ item->identifier() ];
03803     KexiDialogBase * pageSetupDlg = d->pageSetupDialogs[ item->identifier() ];
03804     const bool oldInsideCloseDialog = d->insideCloseDialog;
03805     d->insideCloseDialog = false;
03806      res = closeDialog(pageSetupDlg);
03807     d->insideCloseDialog = oldInsideCloseDialog;
03808     if (!res || ~res) {
03809         return res;
03810     }
03811 
03812 #ifndef KEXI_NO_PENDING_DIALOGS
03813     Private::PendingJobType pendingType;
03814     KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
03815     if (pendingType!=Private::NoJob) {
03816         return cancelled;
03817     }
03818 #else
03819     KexiDialogBase *dlg = d->openedDialogFor( item );
03820 #endif
03821 
03822     if (dlg) {//close existing window
03823 //      if (!dlg->tryClose(true))
03824         const bool tmp = d->forceDialogClosing;
03825         /*const bool remove_on_closing = */dlg->partItem()->neverSaved();
03826         d->forceDialogClosing = true;
03827         res = closeDialog(dlg);
03828         d->forceDialogClosing = tmp; //restore
03829         if (!res || ~res) {
03830             return res;
03831         }
03832 //      if (remove_on_closing) //already removed
03833     //      return true;
03834 //      if (!dlg->close(true))
03835 //          return true; //ok - close cancelled
03836     }
03837 
03838     //in case the dialog is a 'print setup' dialog, also update d->pageSetupDialogs
03839     int dataItemID = d->pageSetupDialogItemID2dataItemID_map[item->identifier()];
03840     d->pageSetupDialogItemID2dataItemID_map.remove(item->identifier());
03841     d->pageSetupDialogs.take( dataItemID );
03842 
03843     if (!d->prj->removeObject(this, *item)) {
03844         //TODO(js) better msg
03845         showSorryMessage( i18n("Could not remove object.") );
03846         return false;
03847     }
03848     return true;
03849 }
03850 
03851 void KexiMainWindowImpl::renameObject( KexiPart::Item *item, const QString& _newName, bool &success )
03852 {
03853     if (userMode()) {
03854         success = false;
03855         return;
03856     }
03857     d->pendingDialogsExist();
03858     QString newName = _newName.stripWhiteSpace();
03859     if (newName.isEmpty()) {
03860         showSorryMessage( i18n("Could not set empty name for this object.") );
03861         success = false;
03862         return;
03863     }
03864     enableMessages(false); //to avoid double messages
03865     const bool res = d->prj->renameObject(this, *item, newName);
03866     enableMessages(true);
03867     if (!res) {
03868         showErrorMessage( d->prj, i18n("Renaming object \"%1\" failed.").arg(newName) );
03869         success = false;
03870         return;
03871     }
03872     d->pendingDialogsExist();
03873 }
03874 
03875 void KexiMainWindowImpl::slotObjectRenamed(const KexiPart::Item &item, const QCString& /*oldName*/)
03876 {
03877 #ifndef KEXI_NO_PENDING_DIALOGS
03878     Private::PendingJobType pendingType;
03879     KexiDialogBase *dlg = d->openedDialogFor( &item, pendingType );
03880     if (pendingType!=Private::NoJob)
03881         return;
03882 #else
03883     KexiDialogBase *dlg = d->openedDialogFor( &item );
03884 #endif
03885     if (!dlg)
03886         return;
03887 
03888     //change item
03889     dlg->updateCaption();
03890     if (static_cast<KexiDialogBase*>(d->curDialog)==dlg)//optionally, update app. caption
03891         updateAppCaption();
03892 }
03893 
03894 int KexiMainWindowImpl::generatePrivateID()
03895 {
03896     return --d->privateIDCounter;
03897 }
03898 
03899 void KexiMainWindowImpl::acceptPropertySetEditing()
03900 {
03901     if (d->propEditor)
03902         d->propEditor->editor()->acceptInput();
03903 }
03904 
03905 void KexiMainWindowImpl::propertySetSwitched(KexiDialogBase *dlg, bool force, 
03906     bool preservePrevSelection, const QCString& propertyToSelect)
03907 {
03908     kdDebug() << "KexiMainWindowImpl::propertySetSwitched() d->curDialog: "
03909         << (d->curDialog ? d->curDialog->caption() : QString("NULL")) << " dlg: " << (dlg ? dlg->caption() : QString("NULL"))<< endl;
03910     if ((KexiDialogBase*)d->curDialog!=dlg) {
03911         d->propBuffer = 0; //we'll need to move to another prop. set
03912         return;
03913     }
03914     if (d->propEditor) {
03915         KoProperty::Set *newBuf = d->curDialog ? d->curDialog->propertySet() : 0;
03916         if (!newBuf || (force || static_cast<KoProperty::Set*>(d->propBuffer) != newBuf)) {
03917             d->propBuffer = newBuf;
03918             if (preservePrevSelection) {
03919                 if (propertyToSelect.isEmpty())
03920                     d->propEditor->editor()->changeSet( d->propBuffer, preservePrevSelection );
03921                 else
03922                     d->propEditor->editor()->changeSet( d->propBuffer, propertyToSelect );
03923             }
03924         }
03925     }
03926 }
03927 
03928 void KexiMainWindowImpl::slotDirtyFlagChanged(KexiDialogBase* dlg)
03929 {
03930     KexiPart::Item *item = dlg->partItem();
03931     //update text in navigator and app. caption
03932     if(!userMode())
03933         d->nav->updateItemName( *item, dlg->dirty() );
03934 
03935     invalidateActions();
03936     updateAppCaption();
03937 }
03938 
03939 void KexiMainWindowImpl::slotMdiModeHasBeenChangedTo(KMdi::MdiMode)
03940 {
03941     //after switching to other MDI mode, pointer to current dialog needs to be updated
03942     activateFirstWin();
03943     activeWindowChanged(activeWindow());
03944 }
03945 
03946 void KexiMainWindowImpl::slotTipOfTheDay()
03947 {
03948     //todo
03949 }
03950 
03951 void KexiMainWindowImpl::slotImportantInfo()
03952 {
03953     importantInfo(false);
03954 }
03955 
03956 void KexiMainWindowImpl::slotStartFeedbackAgent()
03957 {
03958 #ifndef KEXI_NO_FEEDBACK_AGENT
03959 #ifdef FEEDBACK_CLASS
03960     const KAboutData* about = KApplication::kApplication()->aboutData();
03961     FEEDBACK_CLASS* wizard = new FEEDBACK_CLASS( about->programName(),
03962         about->version(), 0, 0, 0, FEEDBACK_CLASS::AllPages );
03963 
03964     if ( wizard->exec() )
03965     {
03966         KApplication::kApplication()->invokeMailer( "kexi-reports-dummy@kexi.org",
03967             QString::null, QString::null,
03968             about->appName() + QCString( " [feedback]" ),
03969             wizard->feedbackDocument().toString( 2 ).local8Bit() );
03970     }
03971 
03972     delete wizard;
03973 #endif
03974 #endif
03975 }
03976 
03977 void KexiMainWindowImpl::importantInfo(bool /*onStartup*/)
03978 {
03979 #if 0
03980     if (onStartup && !d->showImportantInfoOnStartup)
03981         return;
03982 
03983     QString key = QString("showImportantInfo %1").arg(KEXI_VERSION_STRING);
03984     d->config->setGroup("Startup");
03985     bool show = d->config->readBoolEntry(key,true);
03986 
03987     if (show || !onStartup) { //if !onStartup - dialog is always shown
03988         d->config->setGroup("TipOfDay");
03989         if (!d->config->hasKey("RunOnStart"))
03990             d->config->writeEntry("RunOnStart",true);
03991 
03992         QString lang = KGlobal::locale()->language();
03993         QString fname = locate("data", QString("kexi/readme_")+lang);
03994         if (fname.isEmpty())//back to default
03995             fname = locate("data", "kexi/readme_en");
03996         KTipDialog tipDialog(new KTipDatabase(QString::null), 0);
03997         tipDialog.setCaption(i18n("Important Information"));
03998         QObjectList *l = tipDialog.queryList( "KPushButton" );//hack: hide <- -> buttons
03999         int i=0;
04000         for (QObjectListIt it( *l ); it.current() && i<2; ++it, i++ )
04001             static_cast<KPushButton*>(it.current())->hide();
04002         QFile f(fname);
04003         if ( f.open( IO_ReadOnly ) ) {
04004             QTextStream ts(&f);
04005             ts.setCodec( KGlobal::locale()->codecForEncoding() );
04006             QTextBrowser *tb = KexiUtils::findFirstChild<KTextBrowser>(&tipDialog,"KTextBrowser");
04007             if (tb) {
04008                 tb->setText( QString("<qt>%1</qt>").arg(ts.read()) );
04009             }
04010             f.close();
04011         }
04012 
04013         tipDialog.adjustSize();
04014         QRect desk = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber(this) );
04015         tipDialog.resize( QMAX(tipDialog.width(),desk.width()*3/5), QMAX(tipDialog.height(),desk.height()*3/5) );
04016         KDialog::centerOnScreen(&tipDialog);
04017         tipDialog.setModal ( true );
04018         tipDialog.exec();
04019         //a hack: get user's settings
04020         d->config->setGroup("TipOfDay");
04021         show = d->config->readBoolEntry("RunOnStart", show);
04022     }
04023 
04024     //write our settings back
04025     d->config->setGroup("Startup");
04026     d->config->writeEntry(key,show);
04027     d->showImportantInfoOnStartup = false;
04028 #endif
04029 }
04030 
04031 void KexiMainWindowImpl::slotOptionsEnableForms(bool show, bool noMessage)
04032 {
04033     Q_UNUSED(noMessage);
04034     Kexi::tempShowForms() = show;
04035 }
04036 
04037 bool KexiMainWindowImpl::userMode() const
04038 {
04039     return d->userMode;
04040 }
04041 
04042 bool
04043 KexiMainWindowImpl::initUserMode(KexiProjectData *projectData)
04044 {
04045 //  Kexi::tempShowForms() = true;
04046 //  Kexi::tempShowReports() = true;
04047 //  Kexi::tempShowMacros() = true;
04048 //  Kexi::tempShowScripts() = true;
04049     if(!projectData)
04050         return false;
04051 
04052     createKexiProject(projectData); //initialize project
04053 //  d->prj->setFinal(true);         //announce that we are in fianl mode
04054 
04055     tristate res = d->prj->open();             //try to open database
04056     if (!res || ~res) {
04057         delete d->prj;
04058         d->prj = 0;
04059         return false;
04060     }
04061 
04062 #if 0 //todo reenable; autoopen objects are handled elsewhere
04063     KexiDB::TableSchema *sch = d->prj->dbConnection()->tableSchema("kexi__final");
04064     QString err_msg = i18n("Could not start project \"%1\" in Final Mode.")
04065         .arg(static_cast<KexiDB::SchemaData*>(projectData)->name());
04066     if(!sch)
04067     {
04068         hide();
04069         showErrorMessage( err_msg, i18n("No Final Mode data found.") );
04070         return false;
04071     }
04072 
04073     KexiDB::Cursor *c = d->prj->dbConnection()->executeQuery(*sch);
04074     if(!c)
04075     {
04076         hide();
04077         showErrorMessage( err_msg, i18n("Error reading Final Mode data.") );
04078         return false;
04079     }
04080 
04081     QString startupPart;
04082     QString startupItem;
04083     while(c->moveNext())
04084     {
04085         kdDebug() << "KexiMainWinImpl::initFinalMode(): property: [" << c->value(1).toString() << "] " << c->value(2).toString() << endl;
04086         if(c->value(1).toString() == "startup-part")
04087             startupPart = c->value(2).toString();
04088         else if(c->value(1).toString() == "startup-item")
04089             startupItem = c->value(2).toString();
04090         else if(c->value(1).toString() == "mainxmlui")
04091             setXML(c->value(2).toString());
04092     }
04093     d->prj->dbConnection()->deleteCursor(c);
04094 
04095     kdDebug() << "KexiMainWinImpl::initFinalMode(): part: " << startupPart << endl;
04096     kdDebug() << "KexiMainWinImpl::initFinalMode(): item: " << startupItem << endl;
04097 
04098     initActions();
04099     initUserActions();
04100     guiFactory()->addClient(this);
04101     setStandardToolBarMenuEnabled(false);
04102     setHelpMenuEnabled(false);
04103 
04104     KexiPart::Info *i = Kexi::partManager().infoForMimeType(startupPart.latin1());
04105     if (!i) {
04106         hide();
04107         showErrorMessage( err_msg, i18n("Specified plugin does not exist.") );
04108         return false;
04109     }
04110 
04111     Kexi::partManager().part(i);
04112     KexiPart::Item *item = d->prj->item(i, startupItem);
04113     bool openingCancelled;
04114     if(!openObject(item, Kexi::DataViewMode, openingCancelled) && !openingCancelled) {
04115         hide();
04116         showErrorMessage( err_msg, i18n("Specified object could not be opened.") );
04117         return false;
04118     }
04119 
04120     QWidget::setCaption("MyApp");//TODO
04121 #endif
04122     return true;
04123 }
04124 
04125 void
04126 KexiMainWindowImpl::initUserActions()
04127 {
04128 #if 0 //unused for now
04129     KexiDB::Cursor *c = d->prj->dbConnection()->executeQuery("SELECT p_id, name, text, icon, method, arguments FROM kexi__useractions WHERE scope = 0");
04130     if(!c)
04131         return;
04132 
04133     while(c->moveNext())
04134     {
04135         KexiUserAction::fromCurrentRecord(this, actionCollection(), c);
04136     }
04137     d->prj->dbConnection()->deleteCursor(c);
04138 /*
04139     KexiUserAction *a1 = new KexiUserAction(this, actionCollection(), "user_dataview", "Change to dataview", "table");
04140     Arguments args;
04141     args.append(QVariant("kexi/table"));
04142     args.append(QVariant("persons"));
04143     a1->setMethod(KexiUserAction::OpenObject, args);
04144 */
04145 #endif
04146 }
04147 
04148 void KexiMainWindowImpl::slotToolsProjectMigration()
04149 {
04150     showProjectMigrationWizard(QString::null, QString::null);
04151 }
04152 
04153 void KexiMainWindowImpl::slotToolsCompactDatabase()
04154 {
04155     KexiProjectData *data = 0;
04156     KexiDB::Driver *drv = 0;
04157     const bool projectWasOpened = d->prj;
04158 
04159     if (!d->prj) {
04160         KexiStartupDialog dlg(
04161             KexiStartupDialog::OpenExisting, 0, Kexi::connset(), Kexi::recentProjects(),
04162             this, "KexiOpenDialog");
04163 
04164         if (dlg.exec()!=QDialog::Accepted)
04165             return;
04166 
04167         if (dlg.selectedFileName().isEmpty()) {
04169             return;
04170         }
04171         KexiDB::ConnectionData cdata;
04172         cdata.setFileName( dlg.selectedFileName() );
04173         
04174         //detect driver name for the selected file
04175         KexiStartupData::Import detectedImportAction;
04176         tristate res = KexiStartupHandler::detectActionForFile( 
04177             detectedImportAction, cdata.driverName,
04178             "" /*suggestedDriverName*/, cdata.fileName(), 0,
04179             KexiStartupHandler::SkipMessages | KexiStartupHandler::ThisIsAProjectFile 
04180             | KexiStartupHandler::DontConvert);
04181 
04182         if (true==res && !detectedImportAction)
04183             drv = Kexi::driverManager().driver( cdata.driverName );
04184         if (!drv || !(drv->features() & KexiDB::Driver::CompactingDatabaseSupported)) {
04185             KMessageBox::information(this, "<qt>"+
04186                 i18n("Compacting database file <nobr>\"%1\"</nobr> is not supported.")
04187                 .arg(QDir::convertSeparators(cdata.fileName())));
04188             return;
04189         }
04190         data = new KexiProjectData( cdata, cdata.fileName() );
04191     }
04192     else {
04193         //sanity
04194         if ( !(d->prj && d->prj->dbConnection() 
04195             && (d->prj->dbConnection()->driver()->features() & KexiDB::Driver::CompactingDatabaseSupported) ))
04196             return;
04197 
04198         if (KMessageBox::Continue != KMessageBox::warningContinueCancel(this,
04199                 i18n("The current project has to be closed before compacting the database. "
04200                  "It will be open again after compacting.\n\nDo you want to continue?")))
04201             return;
04202 
04203         data = new KexiProjectData(*d->prj->data()); // a copy
04204         drv = d->prj->dbConnection()->driver();
04205         const tristate res = closeProject();
04206         if (~res || !res)
04207             return;
04208     }
04209 
04210     if (!drv->adminTools().vacuum(*data->connectionData(), data->databaseName())) {
04211         //err msg
04212         showErrorMessage( &drv->adminTools() );
04213     }
04214 
04215     if (data && projectWasOpened) {
04216         openProject(*data);
04217         delete data;
04218     }
04219 }
04220 
04221 tristate KexiMainWindowImpl::showProjectMigrationWizard(
04222     const QString& mimeType, const QString& databaseName, const KexiDB::ConnectionData *cdata)
04223 {
04224     //pass arguments
04225     QMap<QString,QString> args;
04226     args.insert("mimeType", mimeType);
04227     args.insert("databaseName", databaseName);
04228     if (cdata) { //pass ConnectionData serialized as a string...
04229         QString str;
04230         KexiUtils::serializeMap( KexiDB::toMap( *cdata ), str );
04231         args.insert("connectionData", str);
04232     }
04233 
04234     QDialog *dlg = KexiInternalPart::createModalDialogInstance("migration", this, this, 0, &args);
04235     if (!dlg)
04236         return false; //error msg has been shown by KexiInternalPart
04237 
04238     const int result = dlg->exec();
04239     delete dlg;
04240     //raise();
04241     if (result!=QDialog::Accepted)
04242         return cancelled;
04243 
04244     //open imported project in a new Kexi instance
04245     QString destinationDatabaseName( args["destinationDatabaseName"] );
04246     QString fileName, destinationConnectionShortcut, dbName;
04247     if (!destinationDatabaseName.isEmpty()) {
04248         if (args.contains("destinationConnectionShortcut")) {
04249             // server-based
04250             destinationConnectionShortcut = args["destinationConnectionShortcut"];
04251         }
04252         else {
04253             // file-based
04254             fileName = destinationDatabaseName;
04255             destinationDatabaseName = QString::null;
04256         }
04257         tristate res = openProject(fileName, destinationConnectionShortcut, 
04258             destinationDatabaseName);
04259         raise();
04260         return res;
04261 //          KexiDB::ConnectionData *connData = new KexiDB::ConnectionData();
04262 //          KexiDB::fromMap( KexiUtils::deserializeMap( args["destinationConnectionData"] ), *connData );
04263 //      return openProject(destinationFileName, 0);
04264     }
04265     return true;
04266 }
04267 
04268 tristate KexiMainWindowImpl::executeItem(KexiPart::Item* item)
04269 {
04270     KexiPart::Info *info = item ? Kexi::partManager().infoForMimeType(item->mimeType()) : 0;
04271     if ( (! info) || (! info->isExecuteSupported()) )
04272         return false;
04273     KexiPart::Part *part = Kexi::partManager().part(info);
04274     if (!part)
04275         return false;
04276     return part->execute(item);
04277 }
04278 
04279 void KexiMainWindowImpl::slotProjectImportDataTable()
04280 {
04282     if (userMode())
04283         return;
04284     QMap<QString,QString> args;
04285     args.insert("sourceType", "file");
04286     QDialog *dlg = KexiInternalPart::createModalDialogInstance(
04287         "csv_importexport", "KexiCSVImportDialog", this, this, 0, &args);
04288     if (!dlg)
04289         return; //error msg has been shown by KexiInternalPart
04290     dlg->exec();
04291     delete dlg;
04292 }
04293 
04294 tristate KexiMainWindowImpl::executeCustomActionForObject(KexiPart::Item* item, 
04295     const QString& actionName)
04296 {
04297     if (actionName == "exportToCSV")
04298         return exportItemAsDataTable(item);
04299     else if (actionName == "copyToClipboardAsCSV")
04300         return copyItemToClipboardAsDataTable(item);
04301 
04302     kexiwarn << "KexiMainWindowImpl::executeCustomActionForObject(): no such action: " 
04303         << actionName << endl;
04304     return false;
04305 }
04306 
04307 tristate KexiMainWindowImpl::exportItemAsDataTable(KexiPart::Item* item)
04308 {
04309     if (!item)
04310         return false;
04313 
04314     QMap<QString,QString> args;
04315     args.insert("destinationType", "file");
04316     args.insert("itemId", QString::number(item->identifier()));
04317     QDialog *dlg = KexiInternalPart::createModalDialogInstance(
04318         "csv_importexport", "KexiCSVExportWizard", this, this, 0, &args);
04319     if (!dlg)
04320         return false; //error msg has been shown by KexiInternalPart
04321     int result = dlg->exec();
04322     delete dlg;
04323     return result == QDialog::Rejected ? cancelled : true;
04324 }
04325 
04326 bool KexiMainWindowImpl::printItem(KexiPart::Item* item, const QString& titleText)
04327 {
04328     return printItem(item, KexiSimplePrintingSettings::load(), titleText);
04329 }
04330 
04331 tristate KexiMainWindowImpl::printItem(KexiPart::Item* item)
04332 {
04333     return printItem(item, QString::null);
04334 }
04335 
04336 bool KexiMainWindowImpl::printItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings,
04337     const QString& titleText)
04338 {
04341     KexiSimplePrintingCommand cmd(this, item->identifier());
04342     //modal
04343     return cmd.print(settings, titleText);
04344 }
04345 
04346 bool KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item, const QString& titleText, bool reload)
04347 {
04348     return printPreviewForItem(item, KexiSimplePrintingSettings::load(), titleText, reload);
04349 }
04350 
04351 tristate KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item)
04352 {
04353     return printPreviewForItem(item, QString::null, 
04355         true/*reload*/);
04356 }
04357 
04358 bool KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item, 
04359     const KexiSimplePrintingSettings& settings, const QString& titleText, bool reload)
04360 {
04363     KexiSimplePrintingCommand* cmd = d->openedCustomObjectsForItem<KexiSimplePrintingCommand>(
04364         item, "KexiSimplePrintingCommand");
04365     if (!cmd) {
04366         d->addOpenedCustomObjectForItem(
04367             item,
04368             cmd = new KexiSimplePrintingCommand(this, item->identifier()), 
04369             "KexiSimplePrintingCommand"
04370         );
04371     }
04372     return cmd->showPrintPreview(settings, titleText, reload);
04373 }
04374 
04375 tristate KexiMainWindowImpl::showPageSetupForItem(KexiPart::Item* item)
04376 {
04379     return printActionForItem(item, PageSetupForItem);
04380 }
04381 
04382 tristate KexiMainWindowImpl::printActionForItem(KexiPart::Item* item, PrintActionType action)
04383 {
04384     if (!item)
04385         return false;
04386     KexiPart::Info *info = Kexi::partManager().infoForMimeType( item->mimeType() );
04387     if (!info->isPrintingSupported())
04388         return false;
04389 
04390     KexiDialogBase *printingDialog = d->pageSetupDialogs[ item->identifier() ];
04391     if (printingDialog) {
04392         if (!activateWindow(printingDialog))
04393             return false;
04394         if (action == PreviewItem || action == PrintItem) {
04395             QTimer::singleShot(0,printingDialog->selectedView(),
04396                 (action == PreviewItem) ? SLOT(printPreview()) : SLOT(print()));
04397         }
04398         return true;
04399     }
04400 
04401 #ifndef KEXI_NO_PENDING_DIALOGS
04402     Private::PendingJobType pendingType;
04403     KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
04404     if (pendingType!=Private::NoJob)
04405         return cancelled;
04406 #else
04407     KexiDialogBase *dlg = d->openedDialogFor( item );
04408 #endif
04409 
04410     if (dlg) {
04411         // accept row changes
04412         QWidget *prevFocusWidget = focusWidget();
04413         dlg->setFocus();
04414         d->action_data_save_row->activate();
04415         if (prevFocusWidget)
04416             prevFocusWidget->setFocus();
04417 
04418         // opened: check if changes made to this dialog are saved, if not: ask for saving
04419         if (dlg->neverSaved()) //sanity check
04420             return false;
04421         if (dlg->dirty()) {
04422             KGuiItem saveChanges( KStdGuiItem::save() ); 
04423             saveChanges.setToolTip(i18n("Save changes"));
04424             saveChanges.setWhatsThis(
04425                 i18n( "Pressing this button will save all recent changes made in \"%1\" object." )
04426                 .arg(item->name()) );
04427             KGuiItem doNotSave( KStdGuiItem::no() );
04428             doNotSave.setWhatsThis(
04429                 i18n( "Pressing this button will ignore all unsaved changes made in \"%1\" object." )
04430                 .arg(dlg->partItem()->name()) );
04431 
04432             QString question;
04433             if (action == PrintItem)
04434                 question = i18n("Do you want to save changes before printing?");
04435             else if (action == PreviewItem)
04436                 question = i18n("Do you want to save changes before making print preview?");
04437             else if (action == PageSetupForItem)
04438                 question = i18n("Do you want to save changes before showing page setup?");
04439             else
04440                 return false;
04441 
04442             const int questionRes = KMessageBox::warningYesNoCancel( this,
04443                 "<p>"+dlg->part()->i18nMessage("Design of object \"%1\" has been modified.", dlg)
04444                 .arg(item->name()) + "</p><p>" + question + "</p>",
04445                 QString::null, 
04446                 saveChanges,
04447                 doNotSave);
04448             if (KMessageBox::Cancel == questionRes)
04449                 return cancelled;
04450             if (KMessageBox::Yes == questionRes) {
04451                 tristate savingRes = saveObject( dlg, QString::null, true /*dontAsk*/ );
04452                 if (true != savingRes)
04453                     return savingRes;
04454             }
04455         }
04456     }
04457     KexiPart::Part * printingPart = Kexi::partManager().partForMimeType("kexi/simpleprinting");
04458     if (!printingPart)
04459         printingPart = new KexiSimplePrintingPart(); //hardcoded as there're no .desktop file
04460     KexiPart::Item* printingPartItem = d->prj->createPartItem(
04461         printingPart, item->name() //<-- this will look like "table1 : printing" on the window list
04462     );
04463     QMap<QString,QString> staticObjectArgs;
04464     staticObjectArgs["identifier"] = QString::number(item->identifier());
04465     if (action == PrintItem)
04466         staticObjectArgs["action"] = "print";
04467     else if (action == PreviewItem)
04468         staticObjectArgs["action"] = "printPreview";
04469     else if (action == PageSetupForItem)
04470         staticObjectArgs["action"] = "pageSetup";
04471     else
04472         return false;
04473     bool openingCancelled;
04474     printingDialog = openObject(printingPartItem, Kexi::DesignViewMode, 
04475         openingCancelled, &staticObjectArgs);
04476     if (openingCancelled)
04477         return cancelled;
04478     if (!printingDialog) //sanity
04479         return false;
04480     d->pageSetupDialogs.insert(item->identifier(), printingDialog);
04481     d->pageSetupDialogItemID2dataItemID_map.insert(
04482         printingDialog->partItem()->identifier(), item->identifier());
04483 
04484     return true;
04485 }
04486 
04487 void KexiMainWindowImpl::slotEditCopySpecialDataTable()
04488 {
04489     KexiPart::Item* item = d->nav->selectedPartItem();
04490     if (item)
04491         exportItemAsDataTable(item);
04492 }
04493 
04494 tristate KexiMainWindowImpl::copyItemToClipboardAsDataTable(KexiPart::Item* item)
04495 {
04496     if (!item)
04497         return false;
04498 
04499     QMap<QString,QString> args;
04500     args.insert("destinationType", "clipboard");
04501     args.insert("itemId", QString::number(item->identifier()));
04502     QDialog *dlg = KexiInternalPart::createModalDialogInstance(
04503         "csv_importexport", "KexiCSVExportWizard", this, this, 0, &args);
04504     if (!dlg)
04505         return false; //error msg has been shown by KexiInternalPart
04506     const int result = dlg->exec();
04507     delete dlg;
04508     return result == QDialog::Rejected ? cancelled : true;
04509 }
04510 
04511 void KexiMainWindowImpl::slotEditPasteSpecialDataTable()
04512 {
04514     if (userMode())
04515         return;
04516     QMap<QString,QString> args;
04517     args.insert("sourceType", "clipboard");
04518     QDialog *dlg = KexiInternalPart::createModalDialogInstance(
04519         "csv_importexport", "KexiCSVImportDialog", this, this, 0, &args);
04520     if (!dlg)
04521         return; //error msg has been shown by KexiInternalPart
04522     dlg->exec();
04523     delete dlg;
04524 }
04525 
04526 void KexiMainWindowImpl::slotEditFind()
04527 {
04528 //  KexiViewBase *view = d->currentViewSupportingAction("edit_findnext");
04529     KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
04530     if (!iface)
04531         return;
04532     d->updateFindDialogContents(true/*create if does not exist*/);
04533     d->findDialog()->setReplaceMode(false);
04534 
04535     d->findDialog()->show();
04536     d->findDialog()->setActiveWindow();
04537     d->findDialog()->raise();
04538 }
04539 
04540 void KexiMainWindowImpl::slotEditFind(bool next)
04541 {
04542     KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
04543     if (!iface)
04544         return;
04545     tristate res = iface->find( 
04546         d->findDialog()->valueToFind(), d->findDialog()->options(), next);
04547     if (~res)
04548         return;
04549     d->findDialog()->updateMessage( true == res );
04551 }
04552 
04553 void KexiMainWindowImpl::slotEditFindNext()
04554 {
04555     slotEditFind( true );
04556 }
04557 
04558 void KexiMainWindowImpl::slotEditFindPrevious()
04559 {
04560     slotEditFind( false );
04561 }
04562 
04563 void KexiMainWindowImpl::slotEditReplace()
04564 {
04565     KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
04566     if (!iface)
04567         return;
04568     d->updateFindDialogContents(true/*create if does not exist*/);
04569     d->findDialog()->setReplaceMode(true);
04571     d->findDialog()->show();
04572     d->findDialog()->setActiveWindow();
04573 }
04574 
04575 void KexiMainWindowImpl::slotEditReplaceNext()
04576 {
04577     slotEditReplace( false );
04578 }
04579 
04580 void KexiMainWindowImpl::slotEditReplace(bool all)
04581 {
04582     KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
04583     if (!iface)
04584         return;
04587     tristate res = iface->findNextAndReplace( 
04588         d->findDialog()->valueToFind(), d->findDialog()->valueToReplaceWith(),
04589         d->findDialog()->options(), all);
04590     d->findDialog()->updateMessage( true == res );
04592 }
04593 
04594 void KexiMainWindowImpl::slotEditReplaceAll()
04595 {
04596     slotEditReplace( true );
04597 }
04598 
04599 void KexiMainWindowImpl::addWindow( KMdiChildView* pView, int flags )
04600 {
04601     //maximize this window, if it's
04604     if (d->maximizeFirstOpenedChildFrm) {
04605         flags |= KMdi::Maximize;
04606         d->maximizeFirstOpenedChildFrm = false;
04607     }
04608     KexiMainWindow::addWindow( pView, flags );
04609 }
04610 
04612 void KexiMainWindowImpl::slotGetNewStuff()
04613 {
04614 #ifdef HAVE_KNEWSTUFF
04615     if(!d->newStuff)
04616         d->newStuff = new KexiNewStuff(this);
04617     d->newStuff->download();
04618     
04619     //KNS::DownloadDialog::open(newstuff->customEngine(), "kexi/template");
04620 #endif
04621 }
04622 
04623 void KexiMainWindowImpl::highlightObject(const QCString& mime, const QCString& name)
04624 {
04625     slotViewNavigator();
04626     if (!d->prj)
04627         return;
04628     KexiPart::Item *item = d->prj->itemForMimeType(mime, name);
04629     if (!item)
04630         return;
04631     if (d->nav) {
04632         d->nav->selectItem(*item);
04633     }
04634 }
04635 
04636 void KexiMainWindowImpl::slotPartItemSelectedInNavigator(KexiPart::Item* item)
04637 {
04638     Q_UNUSED(item);
04639 }
04640 
04641 #include "keximainwindowimpl.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys