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