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