You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4643 lines
153 KiB
4643 lines
153 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
|
|
Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "keximainwindowimpl.h"
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <tqapplication.h>
|
|
#include <tqeventloop.h>
|
|
#include <tqfile.h>
|
|
#include <tqtimer.h>
|
|
#include <tqobjectlist.h>
|
|
#include <tqprocess.h>
|
|
#include <tqtoolbutton.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqmutex.h>
|
|
#include <tqwaitcondition.h>
|
|
#include <tqfiledialog.h>
|
|
#include <tqdockwindow.h>
|
|
#include <tqdockarea.h>
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdecmdlineargs.h>
|
|
#include <tdeaction.h>
|
|
#include <tdelocale.h>
|
|
#include <tdestdaccel.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdeglobal.h>
|
|
#include <kdebug.h>
|
|
#include <kkeydialog.h>
|
|
#include <kedittoolbar.h>
|
|
#include <tdeversion.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <tdeparts/componentfactory.h>
|
|
#include <ktip.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kpushbutton.h>
|
|
#include <ktextbrowser.h>
|
|
#include <kiconloader.h>
|
|
#include <ktabwidget.h>
|
|
#include <kimageio.h>
|
|
#include <khelpmenu.h>
|
|
#include <tdefiledialog.h>
|
|
#include <tderecentdocument.h>
|
|
|
|
#include <kexidb/connection.h>
|
|
#include <kexidb/utils.h>
|
|
#include <kexidb/cursor.h>
|
|
#include <kexidb/dbobjectnamevalidator.h>
|
|
#include <kexidb/admin.h>
|
|
#include <kexiutils/utils.h>
|
|
|
|
//#include "projectsettingsui.h"
|
|
#include "kexiactionproxy.h"
|
|
#include "kexidialogbase.h"
|
|
#include "kexipartmanager.h"
|
|
#include "kexipart.h"
|
|
#include "kexipartinfo.h"
|
|
#include "kexipartguiclient.h"
|
|
#include "kexiproject.h"
|
|
#include "kexiprojectdata.h"
|
|
#include "kexiprojectset.h"
|
|
#include "kexi.h"
|
|
#include "kexistatusbar.h"
|
|
#include "kexiinternalpart.h"
|
|
#include "kexiactioncategories.h"
|
|
#include "kexifinddialog.h"
|
|
#include "kexisearchandreplaceiface.h"
|
|
|
|
#include "kde2_closebutton.xpm"
|
|
|
|
#include <widget/kexibrowser.h>
|
|
#include <widget/kexipropertyeditorview.h>
|
|
#include <widget/utils/kexirecordnavigator.h>
|
|
#include <koproperty/editor.h>
|
|
#include <koproperty/set.h>
|
|
|
|
#include "startup/KexiStartup.h"
|
|
#include "startup/KexiNewProjectWizard.h"
|
|
#include "startup/KexiStartupDialog.h"
|
|
#include "startup/KexiStartupFileDialog.h"
|
|
#include "kexinamedialog.h"
|
|
#include "printing/kexisimpleprintingpart.h"
|
|
#include "printing/kexisimpleprintingpagesetup.h"
|
|
|
|
//Extreme verbose debug
|
|
#if defined(TQ_WS_WIN)
|
|
# include <tderecentdirs.h>
|
|
# include <win32_utils.h>
|
|
//# define KexiVDebug kdDebug()
|
|
#endif
|
|
|
|
#if !defined(KexiVDebug)
|
|
# define KexiVDebug if (0) kdDebug()
|
|
#endif
|
|
|
|
//first fix the geometry
|
|
//#define KEXI_NO_CTXT_HELP 1
|
|
|
|
#ifndef KEXI_NO_CTXT_HELP
|
|
#include <kexicontexthelp.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_TDENEWSTUFF
|
|
#include <tdenewstuff/downloaddialog.h>
|
|
#include "kexinewstuff.h"
|
|
#endif
|
|
|
|
//! @todo REENABLE when blinking and dock
|
|
//! width changes will be removed in KMDI
|
|
//#define PROPEDITOR_VISIBILITY_CHANGES
|
|
|
|
//temporary fix to manage layout
|
|
#include "ksplitter.h"
|
|
#define KDOCKWIDGET_P 1
|
|
|
|
#ifndef KEXI_NO_FEEDBACK_AGENT
|
|
#ifdef FEEDBACK_INCLUDE
|
|
#include FEEDBACK_INCLUDE
|
|
#endif
|
|
#include <tdeapplication.h>
|
|
#include <tdeaboutdata.h>
|
|
#endif
|
|
|
|
#include "keximainwindowimpl_p.h"
|
|
|
|
//-------------------------------------------------
|
|
|
|
//static
|
|
int KexiMainWindowImpl::create(int argc, char *argv[], TDEAboutData* aboutdata)
|
|
{
|
|
Kexi::initCmdLineArgs( argc, argv, aboutdata );
|
|
|
|
bool GUIenabled = true;
|
|
TQWidget *dummyWidget = 0; //needed to have icon for dialogs before KexiMainWindowImpl is created
|
|
//! @todo switch GUIenabled off when needed
|
|
TDEApplication* app = new TDEApplication(true, GUIenabled);
|
|
|
|
#ifdef KEXI_STANDALONE
|
|
TDEGlobal::locale()->removeCatalogue("kexi");
|
|
TDEGlobal::locale()->insertCatalogue("standalone_kexi");
|
|
#endif
|
|
TDEGlobal::locale()->insertCatalogue("koffice");
|
|
TDEGlobal::locale()->insertCatalogue("koproperty");
|
|
|
|
#ifdef CUSTOM_VERSION
|
|
# include "custom_exec.h"
|
|
#endif
|
|
|
|
#ifdef KEXI_DEBUG_GUI
|
|
TQWidget* debugWindow = 0;
|
|
#endif
|
|
if (GUIenabled) {
|
|
dummyWidget = new TQWidget();
|
|
dummyWidget->setIcon( DesktopIcon( "kexi" ) );
|
|
app->setMainWidget(dummyWidget);
|
|
#ifdef KEXI_DEBUG_GUI
|
|
app->config()->setGroup("General");
|
|
if (app->config()->readBoolEntry("showInternalDebugger", false)) {
|
|
debugWindow = KexiUtils::createDebugWindow(0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
tristate res = Kexi::startupHandler().init(argc, argv);
|
|
if (!res || ~res) {
|
|
#ifdef KEXI_DEBUG_GUI
|
|
delete debugWindow;
|
|
#endif
|
|
delete app;
|
|
return (~res) ? 0 : 1;
|
|
}
|
|
|
|
kdDebug() << "startupActions OK" <<endl;
|
|
|
|
/* Exit requested, e.g. after database removing. */
|
|
if (Kexi::startupHandler().action() == KexiStartupData::Exit) {
|
|
#ifdef KEXI_DEBUG_GUI
|
|
delete debugWindow;
|
|
#endif
|
|
delete app;
|
|
return 0;
|
|
}
|
|
|
|
KexiMainWindowImpl *win = new KexiMainWindowImpl();
|
|
app->setMainWidget(win);
|
|
#ifdef KEXI_DEBUG_GUI
|
|
//if (debugWindow)
|
|
//debugWindow->reparent(win, TQPoint(1,1));
|
|
#endif
|
|
delete dummyWidget;
|
|
|
|
if (true != win->startup()) {
|
|
delete win;
|
|
delete app;
|
|
return 1;
|
|
}
|
|
|
|
win->show();
|
|
app->processEvents();//allow refresh our app
|
|
|
|
//#ifdef KEXI_DEBUG_GUI
|
|
// delete debugWindow;
|
|
//#endif
|
|
return 0;
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
|
|
KexiMainWindowImpl::KexiMainWindowImpl()
|
|
: KexiMainWindow()
|
|
, KexiGUIMessageHandler(this)
|
|
, d(new KexiMainWindowImpl::Private(this) )
|
|
{
|
|
KImageIO::registerFormats();
|
|
KexiProjectData *pdata = Kexi::startupHandler().projectData();
|
|
d->userMode = Kexi::startupHandler().forcedUserMode() /* <-- simply forced the user mode */
|
|
/* project has 'user mode' set as default and not 'design mode' override is found: */
|
|
|| (pdata && pdata->userMode() && !Kexi::startupHandler().forcedDesignMode());
|
|
d->isProjectNavigatorVisible = Kexi::startupHandler().isProjectNavigatorVisible();
|
|
|
|
if(userMode())
|
|
kdDebug() << "KexiMainWindowImpl::KexiMainWindowImpl(): starting up in the User Mode" << endl;
|
|
|
|
d->config = kapp->config();
|
|
|
|
if ( !initialGeometrySet() ) {
|
|
int scnum = TQApplication::desktop()->screenNumber(parentWidget());
|
|
TQRect desk = TQApplication::desktop()->screenGeometry(scnum);
|
|
d->config->setGroup("MainWindow");
|
|
TQSize s ( d->config->readNumEntry( TQString::fromLatin1("Width %1").arg(desk.width()), 700 ),
|
|
d->config->readNumEntry( TQString::fromLatin1("Height %1").arg(desk.height()), 480 ) );
|
|
resize (kMin (s.width(), desk.width()), kMin(s.height(), desk.height()));
|
|
}
|
|
|
|
setManagedDockPositionModeEnabled(true);//TODO(js): remove this if will be default in tdemdi :)
|
|
manager()->setSplitterHighResolution(true);
|
|
manager()->setSplitterKeepSize(true);
|
|
setStandardMDIMenuEnabled(false);
|
|
setAsDefaultHost(); //this is default host now.
|
|
TDEGlobal::iconLoader()->addAppDir("kexi");
|
|
TDEGlobal::iconLoader()->addAppDir("koffice");
|
|
|
|
//get informed
|
|
connect(&Kexi::partManager(),TQT_SIGNAL(partLoaded(KexiPart::Part*)),this,TQT_SLOT(slotPartLoaded(KexiPart::Part*)));
|
|
connect( m_pMdi, TQT_SIGNAL(nowMaximized(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotCaptionForCurrentMDIChild(bool)) );
|
|
connect( m_pMdi, TQT_SIGNAL(noMaximizedChildFrmLeft(KMdiChildFrm*)), TQT_TQOBJECT(this), TQT_SLOT(slotNoMaximizedChildFrmLeft(KMdiChildFrm*)));
|
|
// connect( TQT_TQOBJECT(this), TQT_SIGNAL(lastChildFrmClosed()), TQT_TQOBJECT(this), TQT_SLOT(slotLastChildFrmClosed()));
|
|
connect( TQT_TQOBJECT(this), TQT_SIGNAL(lastChildViewClosed()), TQT_TQOBJECT(this), TQT_SLOT(slotLastChildViewClosed()));
|
|
|
|
connect( TQT_TQOBJECT(this), TQT_SIGNAL(childViewIsDetachedNow(TQWidget*)), TQT_TQOBJECT(this), TQT_SLOT(slotChildViewIsDetachedNow(TQWidget*)));
|
|
connect( TQT_TQOBJECT(this), TQT_SIGNAL(mdiModeHasBeenChangedTo(KMdi::MdiMode)),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotMdiModeHasBeenChangedTo(KMdi::MdiMode)));
|
|
|
|
|
|
//if (!userMode()) {
|
|
setXMLFile("kexiui.rc");
|
|
setAcceptDrops(true);
|
|
initActions();
|
|
createShellGUI(true);
|
|
//}
|
|
|
|
d->statusBar = new KexitStatusBar(this, "status_bar");
|
|
|
|
d->origAppCaption = caption();
|
|
|
|
restoreSettings();
|
|
(void)Kexi::smallFont(this/*init*/);
|
|
|
|
if (!userMode()) {
|
|
initContextHelp();
|
|
initPropertyEditor();
|
|
}
|
|
|
|
{//store menu popups list
|
|
TQObjectList *l = queryList( "TQPopupMenu" );
|
|
for (TQObjectListIt it( *l ); it.current(); ++it ) {
|
|
//kdDebug() << "name=" <<it.current()->name() << " cname="<<it.current()->className()<<endl;
|
|
//KexiMainWindowImpl::eventFilter() will filter our popups:
|
|
it.current()->installEventFilter(this);
|
|
d->popups.insert(it.current()->name(), static_cast<TQPopupMenu*>(TQT_TQWIDGET(it.current())));
|
|
}
|
|
delete l;
|
|
d->createMenu = d->popups["create"];
|
|
|
|
#ifdef KEXI_NO_REPORTBUG_COMMAND
|
|
//remove "bug report" action to avoid confusion for supported with commercial technical support
|
|
TQPopupMenu *helpMenu = d->popups["help"];
|
|
if (helpMenu) {
|
|
//const int idx = helpMenu->indexOf( (int)KHelpMenu::menuReportBug );
|
|
helpMenu->removeItemAt(int(KHelpMenu::menuReportBug)-1);
|
|
helpMenu->removeItemAt(int(KHelpMenu::menuReportBug)-1); //separator
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//fix menus a bit more:
|
|
#ifndef KEXI_SHOW_UNIMPLEMENTED
|
|
//disabled (possible crash) d->hideMenuItem("file", i18n("&Import"), true);
|
|
//disabled (possible crash) d->hideMenuItem("help", i18n( "&Report Bug..." ), true);
|
|
#endif
|
|
TDEAction *tdemdi_tooldock_menu_action = childClients()->getFirst() ? childClients()->getFirst()->actionCollection()->action("tdemdi_tooldock_menu") : 0;
|
|
if (tdemdi_tooldock_menu_action) {
|
|
tdemdi_tooldock_menu_action->setEnabled(false);
|
|
}
|
|
|
|
if (!isFakingSDIApplication()/* && !userMode()*/) {
|
|
// TQPopupMenu *menu = (TQPopupMenu*) child( "window", "TDEPopupMenu" );
|
|
TQPopupMenu *menu = d->popups["window"];
|
|
unsigned int count = menuBar()->count();
|
|
if (menu)
|
|
setWindowMenu(menu);
|
|
else
|
|
menuBar()->insertItem( i18n("&Window"), windowMenu(), -1, count-2); // standard position is left to the last ('Help')
|
|
}
|
|
if (userMode()) {
|
|
//hide "insert" menu and disable "project_import", "edit_paste_special" menus
|
|
TQPopupMenu *menu = d->popups["insert"];
|
|
if (menu) {
|
|
for (uint i=0; i < menuBar()->count(); i++) {
|
|
if (menuBar()->text( menuBar()->idAt(i) ) == i18n("&Insert")) {
|
|
menuBar()->setItemVisible( menuBar()->idAt(i), false );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
d->disableMenuItem("file", i18n("&Import"));
|
|
d->disableMenuItem("edit", i18n("Paste &Special"));
|
|
}
|
|
|
|
m_pTaskBar->setCaption(i18n("Task Bar")); //js TODO: move this to KMDIlib
|
|
|
|
// if (!userMode()) {
|
|
invalidateActions();
|
|
d->timer.singleShot(0,this,TQT_SLOT(slotLastActions()));
|
|
// }
|
|
|
|
setTabWidgetVisibility(KMdi::AlwaysShowTabs);
|
|
if (mdiMode()==KMdi::IDEAlMode) {
|
|
d->config->setGroup("MainWindow");
|
|
tabWidget()->setHoverCloseButton(d->config->readBoolEntry("HoverCloseButtonForTabs", false));
|
|
//create special close button as corner widget for IDEAl mode
|
|
TQToolButton *closeButton = new TQToolButton( tabWidget() );
|
|
closeButton->setAutoRaise( true );
|
|
closeButton->setPixmap( TQPixmap( kde2_closebutton ) );
|
|
closeButton->setPaletteBackgroundColor(closeButton->palette().active().background());
|
|
// closeButton->setIconSet(SmallIconSet("tab_remove"));
|
|
tabWidget()->setCornerWidget( closeButton, TQt::TopRight );
|
|
closeButton->hide(); // hide until it's needed to avoid problems in "user mode"
|
|
// when initially the main window is empty
|
|
TQToolTip::add(closeButton,
|
|
i18n("Close the current tab page in Kexi tab interface", "Close the current tab"));
|
|
TQObject::connect( closeButton, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(this), TQT_SLOT( closeActiveView() ) );
|
|
}
|
|
|
|
#ifdef KEXI_ADD_CUSTOM_KEXIMAINWINDOWIMPL
|
|
# include "keximainwindowimpl_ctor.h"
|
|
#endif
|
|
}
|
|
|
|
KexiMainWindowImpl::~KexiMainWindowImpl()
|
|
{
|
|
d->forceDialogClosing=true;
|
|
closeProject();
|
|
delete d;
|
|
}
|
|
|
|
KexiProject *KexiMainWindowImpl::project()
|
|
{
|
|
return d->prj;
|
|
}
|
|
|
|
void KexiMainWindowImpl::setWindowMenu(TQPopupMenu *menu)
|
|
{
|
|
delete m_pWindowMenu;
|
|
m_pWindowMenu = menu;
|
|
int count = menuBar()->count();
|
|
//try to move "window" menu just before "Settings" menu (count-3)
|
|
const TQString txt = i18n("&Window");
|
|
int i;
|
|
for (i=0; i<count; i++) {
|
|
//kdDebug() << menuBar()->text( menuBar()->idAt(i) ) << endl;
|
|
if (txt==menuBar()->text( menuBar()->idAt(i) ))
|
|
break;
|
|
}
|
|
if (i<count) {
|
|
const int id = menuBar()->idAt(i);
|
|
menuBar()->removeItemAt(i);
|
|
menuBar()->insertItem(txt, m_pWindowMenu, id, count-3);
|
|
}
|
|
m_pWindowMenu->setCheckable(true);
|
|
TQObject::connect( m_pWindowMenu, TQT_SIGNAL(aboutToShow()), TQT_TQOBJECT(this), TQT_SLOT(fillWindowMenu()) );
|
|
}
|
|
|
|
void KexiMainWindowImpl::fillWindowMenu()
|
|
{
|
|
KexiMainWindow::fillWindowMenu();
|
|
|
|
/* int i;
|
|
for (i=0; i < (int)m_pWindowMenu->count(); i++) {
|
|
if (m_pWindowMenu->text( m_pWindowMenu->idAt( i ) ) == i18n( "&MDI Mode" )) {
|
|
// kdDebug() << m_pWindowMenu->text( m_pWindowMenu->idAt( i ) ) << endl;
|
|
m_pWindowMenu->removeItem( m_pWindowMenu->idAt( i ) );
|
|
break;
|
|
}
|
|
}*/
|
|
|
|
m_pMdiModeMenu->removeItem( m_pMdiModeMenu->idAt( 0 ) ); //hide toplevel mode
|
|
m_pMdiModeMenu->removeItem( m_pMdiModeMenu->idAt( 1 ) ); //hide tabbed mode
|
|
//update
|
|
if (d->mdiModeToSwitchAfterRestart != (KMdi::MdiMode)0) {
|
|
m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 0 ),
|
|
d->mdiModeToSwitchAfterRestart == KMdi::ChildframeMode );
|
|
m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 1 ),
|
|
d->mdiModeToSwitchAfterRestart == KMdi::IDEAlMode );
|
|
}
|
|
|
|
//insert window_next, window_previous actions:
|
|
// const TQString t = i18n("&Dock/Undock...");
|
|
int i = m_pWindowMenu->count()-1;
|
|
for (int index;; i--) {
|
|
index = m_pWindowMenu->idAt(i);
|
|
if (index==-1 || m_pWindowMenu->text(index).isNull())
|
|
break;
|
|
}
|
|
i++;
|
|
d->action_window_next->plug( m_pWindowMenu, i++ );
|
|
d->action_window_previous->plug( m_pWindowMenu, i++ );
|
|
if (!m_pDocumentViews->isEmpty())
|
|
m_pWindowMenu->insertSeparator( i++ );
|
|
}
|
|
|
|
void KexiMainWindowImpl::switchToIDEAlMode()
|
|
{
|
|
switchToIDEAlMode(true);
|
|
}
|
|
|
|
void KexiMainWindowImpl::switchToIDEAlMode(bool showMessage)
|
|
{
|
|
if (showMessage) {
|
|
if ((int)d->mdiModeToSwitchAfterRestart == 0 && mdiMode()==KMdi::IDEAlMode)
|
|
return;
|
|
if (d->mdiModeToSwitchAfterRestart == KMdi::IDEAlMode)
|
|
return;
|
|
if (mdiMode()==KMdi::IDEAlMode) {//current mode
|
|
d->mdiModeToSwitchAfterRestart = (KMdi::MdiMode)0;
|
|
}
|
|
else {
|
|
KMessageBox::information(this,
|
|
i18n("User interface mode will be switched to IDEAl at next %1 application startup.")
|
|
.arg(KEXI_APP_NAME));
|
|
//delayed
|
|
d->mdiModeToSwitchAfterRestart = KMdi::IDEAlMode;
|
|
}
|
|
}
|
|
else
|
|
KexiMainWindow::switchToIDEAlMode();
|
|
}
|
|
|
|
void KexiMainWindowImpl::switchToChildframeMode()
|
|
{
|
|
switchToChildframeMode(true);
|
|
}
|
|
|
|
void KexiMainWindowImpl::switchToChildframeMode(bool showMessage)
|
|
{
|
|
if (showMessage) {
|
|
if ((int)d->mdiModeToSwitchAfterRestart == 0 && mdiMode()==KMdi::ChildframeMode)
|
|
return;
|
|
if (d->mdiModeToSwitchAfterRestart == KMdi::ChildframeMode)
|
|
return;
|
|
if (mdiMode()==KMdi::ChildframeMode) {//current mode
|
|
d->mdiModeToSwitchAfterRestart = (KMdi::MdiMode)0;
|
|
}
|
|
else {
|
|
KMessageBox::information(this,
|
|
i18n("User interface mode will be switched to Childframe at next %1 application startup.")
|
|
.arg(KEXI_APP_NAME));
|
|
//delayed
|
|
d->mdiModeToSwitchAfterRestart = KMdi::ChildframeMode;
|
|
}
|
|
}
|
|
else
|
|
KexiMainWindow::switchToChildframeMode();
|
|
}
|
|
|
|
TQPopupMenu* KexiMainWindowImpl::findPopupMenu(const char *popupName)
|
|
{
|
|
return d->popups[popupName];
|
|
}
|
|
|
|
TDEActionPtrList KexiMainWindowImpl::allActions() const
|
|
{
|
|
return actionCollection()->actions();
|
|
}
|
|
|
|
KexiDialogBase* KexiMainWindowImpl::currentDialog() const
|
|
{
|
|
return d->curDialog;
|
|
}
|
|
|
|
void KexiMainWindowImpl::initActions()
|
|
{
|
|
// setupGUI(TDEMainWindow::Keys|TDEMainWindow::StatusBar|TDEMainWindow::Save|TDEMainWindow::Create);
|
|
|
|
// d->actionMapper = new TQSignalMapper(this, "act_map");
|
|
// connect(d->actionMapper, TQT_SIGNAL(mapped(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotAction(const TQString &)));
|
|
|
|
// PROJECT MENU
|
|
TDEAction *action = new TDEAction(i18n("&New..."), "document-new", TDEStdAccel::shortcut(TDEStdAccel::New),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectNew()), actionCollection(), "project_new");
|
|
action->setToolTip(i18n("Create a new project"));
|
|
action->setWhatsThis(i18n("Creates a new project. Currently opened project is not affected."));
|
|
|
|
action = KStdAction::open( TQT_TQOBJECT(this), TQT_SLOT( slotProjectOpen() ), actionCollection(), "project_open" );
|
|
action->setToolTip(i18n("Open an existing project"));
|
|
action->setWhatsThis(i18n("Opens an existing project. Currently opened project is not affected."));
|
|
|
|
#ifdef HAVE_TDENEWSTUFF
|
|
action = new TDEAction(i18n("&Download Example Databases..."), "kget", TDEShortcut(0),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotGetNewStuff()), actionCollection(), "project_download_examples");
|
|
action->setToolTip(i18n("Download example databases from the Internet"));
|
|
action->setWhatsThis(i18n("Downloads example databases from the Internet."));
|
|
#endif
|
|
|
|
// d->action_open_recent = KStdAction::openRecent( TQT_TQOBJECT(this), TQT_SLOT(slotProjectOpenRecent(const KURL&)), actionCollection(), "project_open_recent" );
|
|
|
|
//#ifdef KEXI_SHOW_UNIMPLEMENTED
|
|
#ifndef KEXI_NO_UNFINISHED
|
|
d->action_open_recent = new TDEActionMenu(i18n("Open Recent"),
|
|
actionCollection(), "project_open_recent");
|
|
connect(d->action_open_recent->popupMenu(),TQT_SIGNAL(activated(int)),
|
|
this,TQT_SLOT(slotProjectOpenRecent(int)));
|
|
connect(d->action_open_recent->popupMenu(), TQT_SIGNAL(aboutToShow()),
|
|
this,TQT_SLOT(slotProjectOpenRecentAboutToShow()));
|
|
//moved down d->action_open_recent_projects_title_id =
|
|
// d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Opened Databases"));
|
|
//moved down d->action_open_recent_connections_title_id =
|
|
// d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Connected Database Servers"));
|
|
// d->action_open_recent->popupMenu()->insertSeparator();
|
|
// d->action_open_recent_more_id = d->action_open_recent->popupMenu()
|
|
// ->insertItem(i18n("&More Projects..."), TQT_TQOBJECT(this), TQT_SLOT(slotProjectOpenRecentMore()), 0, 1000);
|
|
#else
|
|
d->action_open_recent = d->dummy_action;
|
|
#endif
|
|
|
|
d->action_save = KStdAction::save(
|
|
TQT_TQOBJECT(this), TQT_SLOT( slotProjectSave() ), actionCollection(), "project_save" );
|
|
// d->action_save = new TDEAction(i18n("&Save"), "document-save", TDEStdAccel::shortcut(TDEStdAccel::Save),
|
|
// TQT_TQOBJECT(this), TQT_SLOT(slotProjectSave()), actionCollection(), "project_save");
|
|
d->action_save->setToolTip(i18n("Save object changes"));
|
|
d->action_save->setWhatsThis(i18n("Saves object changes from currently selected window."));
|
|
|
|
#ifdef KEXI_SHOW_UNIMPLEMENTED
|
|
d->action_save_as = new TDEAction(i18n("Save &As..."), "document-save-as", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectSaveAs()), actionCollection(), "project_saveas");
|
|
d->action_save_as->setToolTip(i18n("Save object as"));
|
|
d->action_save_as->setWhatsThis(
|
|
i18n("Saves object changes from currently selected window under a new name (within the same project)."));
|
|
|
|
d->action_project_properties = new TDEAction(i18n("Project Properties"), "application-vnd.tde.info", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectProperties()), actionCollection(), "project_properties");
|
|
#else
|
|
d->action_save_as = d->dummy_action;
|
|
d->action_project_properties = d->dummy_action;
|
|
#endif
|
|
|
|
d->action_close = new TDEAction(i18n("&Close Project"), "window-close", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectClose()), actionCollection(), "project_close" );
|
|
d->action_close->setToolTip(i18n("Close the current project"));
|
|
d->action_close->setWhatsThis(i18n("Closes the current project."));
|
|
|
|
KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT(slotProjectQuit()), actionCollection(), "quit");
|
|
|
|
#ifdef KEXI_SHOW_UNIMPLEMENTED
|
|
d->action_project_relations = new TDEAction(i18n("&Relationships..."), "relation", TQt::CTRL + TQt::Key_R,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectRelations()), actionCollection(), "project_relations");
|
|
d->action_project_relations->setToolTip(i18n("Project relationships"));
|
|
d->action_project_relations->setWhatsThis(i18n("Shows project relationships."));
|
|
|
|
#else
|
|
d->action_project_relations = d->dummy_action;
|
|
#endif
|
|
d->action_tools_data_migration = new TDEAction(
|
|
i18n("&Import Database..."), "database_import", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotToolsProjectMigration()), actionCollection(), "tools_import_project");
|
|
d->action_tools_data_migration->setToolTip(i18n("Import entire database as a Kexi project"));
|
|
d->action_tools_data_migration->setWhatsThis(i18n("Imports entire database as a Kexi project."));
|
|
|
|
d->action_tools_compact_database = new TDEAction(
|
|
i18n("&Compact Database..."), "", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotToolsCompactDatabase()), actionCollection(), "tools_compact_database");
|
|
d->action_tools_compact_database->setToolTip(i18n("Compact the current database project"));
|
|
d->action_tools_compact_database->setWhatsThis(
|
|
i18n("Compacts the current database project, so it will take less space and work faster."));
|
|
|
|
if (userMode())
|
|
d->action_project_import_data_table = 0;
|
|
else {
|
|
d->action_project_import_data_table = new TDEAction(
|
|
i18n("Import->Table Data From File...", "Table Data From &File..."),
|
|
"table"/*! @todo: change to "file_import" or so*/,
|
|
0, TQT_TQOBJECT(this), TQT_SLOT(slotProjectImportDataTable()), actionCollection(),
|
|
"project_import_data_table");
|
|
d->action_project_import_data_table->setToolTip(i18n("Import table data from a file"));
|
|
d->action_project_import_data_table->setWhatsThis(i18n("Imports table data from a file."));
|
|
}
|
|
|
|
d->action_project_export_data_table = new TDEAction(i18n("Export->Table or Query Data to File...",
|
|
"Table or Query Data to &File..."),
|
|
"table"/*! @todo: change to "file_export" or so*/,
|
|
0, TQT_TQOBJECT(this), TQT_SLOT(slotProjectExportDataTable()), actionCollection(),
|
|
"project_export_data_table");
|
|
d->action_project_export_data_table->setToolTip(
|
|
i18n("Export data from the active table or query data to a file"));
|
|
d->action_project_export_data_table->setWhatsThis(
|
|
i18n("Exports data from the active table or query data to a file."));
|
|
|
|
//TODO new TDEAction(i18n("From File..."), "document-open", 0,
|
|
//TODO TQT_TQOBJECT(this), TQT_SLOT(slotImportFile()), actionCollection(), "project_import_file");
|
|
//TODO new TDEAction(i18n("From Server..."), "server", 0,
|
|
//TODO TQT_TQOBJECT(this), TQT_SLOT(slotImportServer()), actionCollection(), "project_import_server");
|
|
|
|
d->action_project_print = KStdAction::print(TQT_TQOBJECT(this), TQT_SLOT(slotProjectPrint()),
|
|
actionCollection(), "project_print" );
|
|
d->action_project_print->setToolTip(i18n("Print data from the active table or query"));
|
|
d->action_project_print->setWhatsThis(i18n("Prints data from the active table or query."));
|
|
|
|
d->action_project_print_preview = KStdAction::printPreview(
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotProjectPrintPreview()),
|
|
actionCollection(), "project_print_preview" );
|
|
d->action_project_print_preview->setToolTip(
|
|
i18n("Show print preview for the active table or query"));
|
|
d->action_project_print_preview->setWhatsThis(
|
|
i18n("Shows print preview for the active table or query."));
|
|
|
|
d->action_project_print_setup = new TDEAction(i18n("Page Set&up..."),
|
|
"", 0, TQT_TQOBJECT(this), TQT_SLOT(slotProjectPageSetup()), actionCollection(),
|
|
"project_print_setup");
|
|
d->action_project_print_setup->setToolTip(
|
|
i18n("Show page setup for printing the active table or query"));
|
|
d->action_project_print_setup->setWhatsThis(
|
|
i18n("Shows page setup for printing the active table or query."));
|
|
|
|
//EDIT MENU
|
|
d->action_edit_cut = createSharedAction( KStdAction::Cut, "edit_cut");
|
|
d->action_edit_copy = createSharedAction( KStdAction::Copy, "edit_copy");
|
|
d->action_edit_paste = createSharedAction( KStdAction::Paste, "edit_paste");
|
|
|
|
if (userMode())
|
|
d->action_edit_paste_special_data_table = 0;
|
|
else {
|
|
d->action_edit_paste_special_data_table =
|
|
new TDEAction(i18n("Paste Special->As Data &Table...", "As Data &Table..."),
|
|
"table", 0, TQT_TQOBJECT(this), TQT_SLOT(slotEditPasteSpecialDataTable()),
|
|
actionCollection(), "edit_paste_special_data_table");
|
|
d->action_edit_paste_special_data_table->setToolTip(
|
|
i18n("Paste clipboard data as a table"));
|
|
d->action_edit_paste_special_data_table->setWhatsThis(
|
|
i18n("Pastes clipboard data to a table."));
|
|
}
|
|
|
|
d->action_edit_copy_special_data_table =
|
|
new TDEAction(i18n("Copy Special->Table or Query Data...",
|
|
"Table or Query as Data Table..."),
|
|
"table", 0, TQT_TQOBJECT(this), TQT_SLOT(slotEditCopySpecialDataTable()),
|
|
actionCollection(), "edit_copy_special_data_table");
|
|
d->action_edit_copy_special_data_table->setToolTip(
|
|
i18n("Copy selected table or query data to clipboard"));
|
|
d->action_edit_copy_special_data_table->setWhatsThis(
|
|
i18n("Copies selected table or query data to clipboard."));
|
|
|
|
d->action_edit_undo = createSharedAction( KStdAction::Undo, "edit_undo");
|
|
d->action_edit_undo->setWhatsThis(i18n("Reverts the most recent editing action."));
|
|
d->action_edit_redo = createSharedAction( KStdAction::Redo, "edit_redo");
|
|
d->action_edit_redo->setWhatsThis(i18n("Reverts the most recent undo action."));
|
|
|
|
#if 0 //old
|
|
d->action_edit_find = createSharedAction( KStdAction::Find, "edit_find");
|
|
d->action_edit_findnext = createSharedAction( KStdAction::FindNext, "edit_findnext");
|
|
d->action_edit_findprev = createSharedAction( KStdAction::FindPrev, "edit_findprevious");
|
|
//! @todo d->action_edit_paste = createSharedAction( KStdAction::Replace, "edit_replace");
|
|
#endif
|
|
|
|
d->action_edit_find = KStdAction::find(
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotEditFind()), actionCollection(), "edit_find" );
|
|
// d->action_edit_find = createSharedAction( KStdAction::Find, "edit_find");
|
|
d->action_edit_findnext = KStdAction::findNext(
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotEditFindNext()), actionCollection(), "edit_findnext");
|
|
d->action_edit_findprev = KStdAction::findPrev(
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotEditFindPrevious()), actionCollection(), "edit_findprevious");
|
|
d->action_edit_replace = 0;
|
|
//! @todo d->action_edit_replace = KStdAction::replace(
|
|
//! TQT_TQOBJECT(this), TQT_SLOT(slotEditReplace()), actionCollection(), "project_print_preview" );
|
|
d->action_edit_replace_all = 0;
|
|
//! @todo d->action_edit_replace_all = new TDEAction( i18n("Replace All"), "", 0,
|
|
//! TQT_TQOBJECT(this), TQT_SLOT(slotEditReplaceAll()), actionCollection(), "edit_replaceall");
|
|
|
|
d->action_edit_select_all = createSharedAction( KStdAction::SelectAll, "edit_select_all");
|
|
|
|
d->action_edit_delete = createSharedAction(i18n("&Delete"), "edit-delete",
|
|
0/*TQt::Key_Delete*/, "edit_delete");
|
|
d->action_edit_delete->setToolTip(i18n("Delete selected object"));
|
|
d->action_edit_delete->setWhatsThis(i18n("Deletes currently selected object."));
|
|
|
|
d->action_edit_delete_row = createSharedAction(i18n("Delete Row"), "delete_table_row",
|
|
TQt::CTRL+TQt::Key_Delete, "edit_delete_row");
|
|
d->action_edit_delete_row->setToolTip(i18n("Delete currently selected row"));
|
|
d->action_edit_delete_row->setWhatsThis(i18n("Deletes currently selected row."));
|
|
|
|
d->action_edit_clear_table = createSharedAction(i18n("Clear Table Contents"), "clear_table_contents",
|
|
0, "edit_clear_table");
|
|
d->action_edit_clear_table->setToolTip(i18n("Clear table contents"));
|
|
d->action_edit_clear_table->setWhatsThis(i18n("Clears table contents."));
|
|
setActionVolatile( d->action_edit_clear_table, true );
|
|
|
|
d->action_edit_edititem = createSharedAction(i18n("Edit Item"), 0, 0, /* CONFLICT in TV: TQt::Key_F2, */
|
|
"edit_edititem");
|
|
d->action_edit_edititem->setToolTip(i18n("Edit currently selected item"));
|
|
d->action_edit_edititem->setWhatsThis(i18n("Edits currently selected item."));
|
|
|
|
d->action_edit_insert_empty_row = createSharedAction(i18n("&Insert Empty Row"), "insert_table_row",
|
|
TQt::SHIFT | TQt::CTRL | TQt::Key_Insert, "edit_insert_empty_row");
|
|
setActionVolatile( d->action_edit_insert_empty_row, true );
|
|
d->action_edit_insert_empty_row->setToolTip(i18n("Insert one empty row above"));
|
|
d->action_edit_insert_empty_row->setWhatsThis(i18n("Inserts one empty row above currently selected table row."));
|
|
|
|
//VIEW MENU
|
|
if (!userMode()) {
|
|
d->action_view_data_mode = new TDERadioAction(i18n("&Data View"), "state_data", TQt::Key_F6,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewDataMode()), actionCollection(), "view_data_mode");
|
|
d->actions_for_view_modes.insert( Kexi::DataViewMode, d->action_view_data_mode );
|
|
d->action_view_data_mode->setExclusiveGroup("view_mode");
|
|
d->action_view_data_mode->setToolTip(i18n("Switch to data view"));
|
|
d->action_view_data_mode->setWhatsThis(i18n("Switches to data view."));
|
|
}
|
|
else
|
|
d->action_view_data_mode = 0;
|
|
|
|
if (!userMode()) {
|
|
d->action_view_design_mode = new TDERadioAction(i18n("D&esign View"), "state_edit", TQt::Key_F7,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewDesignMode()), actionCollection(), "view_design_mode");
|
|
d->actions_for_view_modes.insert( Kexi::DesignViewMode, d->action_view_design_mode );
|
|
d->action_view_design_mode->setExclusiveGroup("view_mode");
|
|
d->action_view_design_mode->setToolTip(i18n("Switch to design view"));
|
|
d->action_view_design_mode->setWhatsThis(i18n("Switches to design view."));
|
|
}
|
|
else
|
|
d->action_view_design_mode = 0;
|
|
|
|
if (!userMode()) {
|
|
d->action_view_text_mode = new TDERadioAction(i18n("&Text View"), "state_sql", TQt::Key_F8,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewTextMode()), actionCollection(), "view_text_mode");
|
|
d->actions_for_view_modes.insert( Kexi::TextViewMode, d->action_view_text_mode );
|
|
d->action_view_text_mode->setExclusiveGroup("view_mode");
|
|
d->action_view_text_mode->setToolTip(i18n("Switch to text view"));
|
|
d->action_view_text_mode->setWhatsThis(i18n("Switches to text view."));
|
|
}
|
|
else
|
|
d->action_view_text_mode = 0;
|
|
|
|
if (d->isProjectNavigatorVisible) {
|
|
d->action_view_nav = new TDEAction(i18n("Project Navigator"), "", TQt::ALT + TQt::Key_1,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewNavigator()), actionCollection(), "view_navigator");
|
|
d->action_view_nav->setToolTip(i18n("Go to project navigator panel"));
|
|
d->action_view_nav->setWhatsThis(i18n("Goes to project navigator panel."));
|
|
}
|
|
else
|
|
d->action_view_nav = 0;
|
|
|
|
d->action_view_mainarea = new TDEAction(i18n("Main Area"), "", TQt::ALT + TQt::Key_2,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewMainArea()), actionCollection(), "view_mainarea");
|
|
d->action_view_mainarea->setToolTip(i18n("Go to main area"));
|
|
d->action_view_mainarea->setWhatsThis(i18n("Goes to main area."));
|
|
|
|
if (!userMode()) {
|
|
d->action_view_propeditor = new TDEAction(i18n("Property Editor"), "", TQt::ALT + TQt::Key_3,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotViewPropertyEditor()), actionCollection(), "view_propeditor");
|
|
d->action_view_propeditor->setToolTip(i18n("Go to property editor panel"));
|
|
d->action_view_propeditor->setWhatsThis(i18n("Goes to property editor panel."));
|
|
}
|
|
else
|
|
d->action_view_propeditor = 0;
|
|
|
|
//DATA MENU
|
|
d->action_data_save_row = createSharedAction(i18n("&Save Row"), "button_ok",
|
|
TQt::SHIFT | TQt::Key_Return, "data_save_row");
|
|
d->action_data_save_row->setToolTip(i18n("Save changes made to the current row"));
|
|
d->action_data_save_row->setWhatsThis(i18n("Saves changes made to the current row."));
|
|
//temp. disable because of problems with volatile actions setActionVolatile( d->action_data_save_row, true );
|
|
|
|
d->action_data_cancel_row_changes = createSharedAction(i18n("&Cancel Row Changes"),
|
|
"button_cancel", 0 , "data_cancel_row_changes");
|
|
d->action_data_cancel_row_changes->setToolTip(i18n("Cancel changes made to the current row"));
|
|
d->action_data_cancel_row_changes->setWhatsThis(i18n("Cancels changes made to the current row."));
|
|
//temp. disable because of problems with volatile actions setActionVolatile( d->action_data_cancel_row_changes, true );
|
|
|
|
d->action_data_execute = createSharedAction(i18n("&Execute"), "media-playback-start", 0 , "data_execute");
|
|
//d->action_data_execute->setToolTip(i18n("")); //TODO
|
|
//d->action_data_execute->setWhatsThis(i18n("")); //TODO
|
|
|
|
#ifndef KEXI_NO_UNFINISHED
|
|
action = createSharedAction(i18n("&Filter"), "filter", 0, "data_filter");
|
|
setActionVolatile( action, true );
|
|
#endif
|
|
// action->setToolTip(i18n("")); //todo
|
|
// action->setWhatsThis(i18n("")); //todo
|
|
|
|
// setSharedMenu("data_sort");
|
|
action = createSharedAction(i18n("&Ascending"), "sort_az", 0, "data_sort_az");
|
|
//temp. disable because of problems with volatile actions setActionVolatile( action, true );
|
|
action->setToolTip(i18n("Sort data in ascending order"));
|
|
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."));
|
|
|
|
action = createSharedAction(i18n("&Descending"), "sort_za", 0, "data_sort_za");
|
|
//temp. disable because of problems with volatile actions setActionVolatile( action, true );
|
|
action->setToolTip(i18n("Sort data in descending order"));
|
|
action->setWhatsThis(i18n("Sorts data in descending (from Z to A and from 9 to 0). Data from selected column is used for sorting."));
|
|
|
|
// - record-navigation related actions
|
|
createSharedAction( KexiRecordNavigator::Actions::moveToFirstRecord(), 0, "data_go_to_first_record");
|
|
createSharedAction( KexiRecordNavigator::Actions::moveToPreviousRecord(), 0, "data_go_to_previous_record");
|
|
createSharedAction( KexiRecordNavigator::Actions::moveToNextRecord(), 0, "data_go_to_next_record");
|
|
createSharedAction( KexiRecordNavigator::Actions::moveToLastRecord(), 0, "data_go_to_last_record");
|
|
createSharedAction( KexiRecordNavigator::Actions::moveToNewRecord(), 0, "data_go_to_new_record");
|
|
|
|
//FORMAT MENU
|
|
d->action_format_font = createSharedAction(i18n("&Font..."), "fonts", 0, "format_font");
|
|
d->action_format_font->setToolTip(i18n("Change font for selected object"));
|
|
d->action_format_font->setWhatsThis(i18n("Changes font for selected object."));
|
|
|
|
//TOOLS MENU
|
|
|
|
//WINDOW MENU
|
|
#ifndef TQ_WS_WIN
|
|
//KMDI <= 3.5.1 has no shortcut here:
|
|
TDEAction *closeWindowAction = actionCollection()->action("window_close");
|
|
if (closeWindowAction)
|
|
closeWindowAction->setShortcut(TDEStdAccel::close());
|
|
#endif
|
|
|
|
//additional 'Window' menu items
|
|
d->action_window_next = new TDEAction( i18n("&Next Window"), "",
|
|
#ifdef TQ_WS_WIN
|
|
TQt::CTRL+TQt::Key_Tab,
|
|
#else
|
|
TQt::ALT+TQt::Key_Right,
|
|
#endif
|
|
TQT_TQOBJECT(this), TQT_SLOT(activateNextWin()), actionCollection(), "window_next");
|
|
d->action_window_next->setToolTip( i18n("Next window") );
|
|
d->action_window_next->setWhatsThis(i18n("Switches to the next window."));
|
|
|
|
d->action_window_previous = new TDEAction( i18n("&Previous Window"), "",
|
|
#ifdef TQ_WS_WIN
|
|
TQt::CTRL+TQt::SHIFT+TQt::Key_Tab,
|
|
#else
|
|
TQt::ALT+TQt::Key_Left,
|
|
#endif
|
|
TQT_TQOBJECT(this), TQT_SLOT(activatePrevWin()), actionCollection(), "window_previous");
|
|
d->action_window_previous->setToolTip( i18n("Previous window") );
|
|
d->action_window_previous->setWhatsThis(i18n("Switches to the previous window."));
|
|
|
|
//SETTINGS MENU
|
|
setStandardToolBarMenuEnabled( true );
|
|
action = KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT( slotConfigureKeys() ), actionCollection() );
|
|
action->setWhatsThis(i18n("Lets you configure shortcut keys."));
|
|
|
|
#ifdef KEXI_SHOW_UNIMPLEMENTED
|
|
action = KStdAction::configureToolbars( TQT_TQOBJECT(this), TQT_SLOT( slotConfigureToolbars() ), actionCollection() );
|
|
action->setWhatsThis(i18n("Lets you configure toolbars."));
|
|
|
|
d->action_show_other = new TDEActionMenu(i18n("Other"),
|
|
actionCollection(), "options_show_other");
|
|
#endif
|
|
|
|
#ifndef KEXI_NO_CTXT_HELP
|
|
d->action_show_helper = new TDEToggleAction(i18n("Show Context Help"), "", TQt::CTRL + TQt::Key_H,
|
|
actionCollection(), "options_show_contexthelp");
|
|
#if KDE_IS_VERSION(3,2,90)
|
|
d->action_show_helper->setCheckedState(i18n("Hide Context Help"));
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef KEXI_FORMS_SUPPORT
|
|
slotOptionsEnableForms(true, true);
|
|
#else
|
|
slotOptionsEnableForms(false, true);
|
|
#endif
|
|
|
|
#ifdef KEXI_REPORTS_SUPPORT
|
|
Kexi::tempShowReports() = true;
|
|
#else
|
|
Kexi::tempShowReports() = false;
|
|
#endif
|
|
|
|
#ifdef KEXI_MACROS_SUPPORT
|
|
Kexi::tempShowMacros() = true;
|
|
#else
|
|
Kexi::tempShowMacros() = false;
|
|
#endif
|
|
|
|
#ifdef KEXI_SCRIPTS_SUPPORT
|
|
Kexi::tempShowScripts() = true;
|
|
#else
|
|
Kexi::tempShowScripts() = false;
|
|
#endif
|
|
|
|
#ifdef KEXI_SHOW_UNIMPLEMENTED
|
|
d->action_configure = KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotShowSettings()), actionCollection());
|
|
action->setWhatsThis(i18n("Lets you configure Kexi."));
|
|
#endif
|
|
|
|
//HELP MENU
|
|
#if 0//js: todo reenable later
|
|
KStdAction::tipOfDay( TQT_TQOBJECT(this), TQT_SLOT( slotTipOfTheDayAction() ), actionCollection() )
|
|
->setWhatsThis(i18n("This shows useful tips on the use of this application."));
|
|
#endif
|
|
#if 0 //we don't have a time for updating info text for each new version
|
|
new TDEAction(i18n("Important Information"), "messagebox_info", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotImportantInfo()), actionCollection(), "help_show_important_info");
|
|
#endif
|
|
//TODO: UNCOMMENT TO REMOVE MDI MODES SETTING m_pMdiModeMenu->hide();
|
|
|
|
#ifndef KEXI_NO_FEEDBACK_AGENT
|
|
#ifdef FEEDBACK_CLASS
|
|
new TDEAction(i18n("Give Feedback..."), "messagebox_info", 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotStartFeedbackAgent()), actionCollection(), "help_start_feedback_agent");
|
|
#endif
|
|
#endif
|
|
// TDEAction *actionSettings = new TDEAction(i18n("Configure Kexi..."), "configure", 0,
|
|
// actionCollection(), "kexi_settings");
|
|
// actionSettings->setWhatsThis(i18n("Lets you configure Kexi."));
|
|
// connect(actionSettings, TQT_SIGNAL(activated()), TQT_TQOBJECT(this), TQT_SLOT(slotShowSettings()));
|
|
|
|
// -- add a few missing tooltips (usable especially in Form's "Assign action" dialog)
|
|
if ((action = actionCollection()->action("window_close")))
|
|
action->setToolTip(i18n("Close the current window"));
|
|
|
|
// ----- declare action categories, so form's "assign action to button"
|
|
// (and macros in the future) will be able to recognize category
|
|
// of actions and filter them -----------------------------------
|
|
//! @todo shouldn't we move this to core?
|
|
Kexi::ActionCategories *acat = Kexi::actionCategories();
|
|
acat->addAction("data_execute", Kexi::PartItemActionCategory);
|
|
|
|
//! @todo unused for now
|
|
acat->addWindowAction("data_filter",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addWindowAction("data_save_row",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addWindowAction("data_cancel_row_changes",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addWindowAction("delete_table_row",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
//! @todo support this in KexiPart::FormObjectType as well
|
|
acat->addWindowAction("data_sort_az",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
//! @todo support this in KexiPart::FormObjectType as well
|
|
acat->addWindowAction("data_sort_za",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
//! @todo support this in KexiPart::FormObjectType as well
|
|
acat->addWindowAction("edit_clear_table",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
//! @todo support this in KexiPart::FormObjectType as well
|
|
acat->addWindowAction("edit_copy_special_data_table",
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
// GlobalActions, etc.
|
|
acat->addAction("edit_copy", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
|
|
|
|
acat->addAction("edit_cut", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
|
|
|
|
acat->addAction("edit_paste", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory);
|
|
|
|
acat->addAction("edit_delete", Kexi::GlobalActionCategory|Kexi::PartItemActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_delete_row", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_edititem", Kexi::PartItemActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
acat->addAction("edit_find", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_findnext", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_findprevious", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_replace", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
acat->addAction("edit_paste_special_data_table", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("help_about_app", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("help_about_kde", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("help_contents", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("help_report_bug", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("help_whats_this", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("options_configure_keybinding", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("project_close", Kexi::GlobalActionCategory);
|
|
|
|
//! @todo support this in FormObjectType as well
|
|
acat->addAction("project_export_data_table", Kexi::GlobalActionCategory|Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
acat->addAction("project_import_data_table", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("project_new", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("project_open", Kexi::GlobalActionCategory);
|
|
|
|
//! @todo support this in FormObjectType, ReportObjectType as well as others
|
|
acat->addAction("project_print", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
//! @todo support this in FormObjectType, ReportObjectType as well as others
|
|
acat->addAction("project_print_preview", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
//! @todo support this in FormObjectType, ReportObjectType as well as others
|
|
acat->addAction("project_print_setup", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType);
|
|
|
|
acat->addAction("quit", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("tools_compact_database", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("tools_import_project", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_data_mode", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_design_mode", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_text_mode", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_mainarea", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_navigator", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("view_propeditor", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("window_close", Kexi::GlobalActionCategory | Kexi::WindowActionCategory);
|
|
acat->setAllObjectTypesSupported("window_close", true);
|
|
|
|
acat->addAction("window_next", Kexi::GlobalActionCategory);
|
|
|
|
acat->addAction("window_previous", Kexi::GlobalActionCategory);
|
|
|
|
//skipped - design view only
|
|
acat->addAction("format_font", Kexi::NoActionCategory);
|
|
acat->addAction("project_save", Kexi::NoActionCategory);
|
|
acat->addAction("edit_insert_empty_row", Kexi::NoActionCategory);
|
|
//! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType later
|
|
acat->addAction("edit_select_all", Kexi::NoActionCategory);
|
|
//! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType later
|
|
acat->addAction("edit_redo", Kexi::NoActionCategory);
|
|
//! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType later
|
|
acat->addAction("edit_undo", Kexi::NoActionCategory);
|
|
|
|
//record-navigation related actions
|
|
acat->addAction("data_go_to_first_record", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
acat->addAction("data_go_to_previous_record", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
acat->addAction("data_go_to_next_record", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
acat->addAction("data_go_to_last_record", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
acat->addAction("data_go_to_new_record", Kexi::WindowActionCategory,
|
|
KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType);
|
|
|
|
//skipped - internal:
|
|
acat->addAction("tablepart_create", Kexi::NoActionCategory);
|
|
acat->addAction("querypart_create", Kexi::NoActionCategory);
|
|
acat->addAction("formpart_create", Kexi::NoActionCategory);
|
|
acat->addAction("reportpart_create", Kexi::NoActionCategory);
|
|
acat->addAction("macropart_create", Kexi::NoActionCategory);
|
|
acat->addAction("scriptpart_create", Kexi::NoActionCategory);
|
|
}
|
|
|
|
void KexiMainWindowImpl::invalidateActions()
|
|
{
|
|
invalidateProjectWideActions();
|
|
invalidateSharedActions();
|
|
}
|
|
|
|
void KexiMainWindowImpl::invalidateSharedActions(TQObject *o)
|
|
{
|
|
//TODO: enabling is more complex...
|
|
/* d->action_edit_cut->setEnabled(true);
|
|
d->action_edit_copy->setEnabled(true);
|
|
d->action_edit_paste->setEnabled(true);*/
|
|
|
|
if (!o)
|
|
o = TQT_TQOBJECT(focusWindow());
|
|
KexiSharedActionHost::invalidateSharedActions(o);
|
|
}
|
|
|
|
void KexiMainWindowImpl::invalidateSharedActions()
|
|
{
|
|
invalidateSharedActions(0);
|
|
}
|
|
|
|
// unused, I think
|
|
void KexiMainWindowImpl::invalidateSharedActionsLater()
|
|
{
|
|
TQTimer::singleShot(1, TQT_TQOBJECT(this), TQT_SLOT(invalidateSharedActions()));
|
|
}
|
|
|
|
void KexiMainWindowImpl::invalidateProjectWideActions()
|
|
{
|
|
// stateChanged("project_opened",d->prj ? StateNoReverse : StateReverse);
|
|
|
|
const bool have_dialog = d->curDialog;
|
|
const bool dialog_dirty = d->curDialog && d->curDialog->dirty();
|
|
const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->isReadOnly();
|
|
|
|
//PROJECT MENU
|
|
d->action_save->setEnabled(have_dialog && dialog_dirty && !readOnly);
|
|
d->action_save_as->setEnabled(have_dialog && !readOnly);
|
|
d->action_project_properties->setEnabled(d->prj);
|
|
d->action_close->setEnabled(d->prj);
|
|
d->action_project_relations->setEnabled(d->prj);
|
|
if (d->action_project_import_data_table)
|
|
d->action_project_import_data_table->setEnabled(d->prj && !readOnly);
|
|
d->action_project_export_data_table->setEnabled(
|
|
d->curDialog && d->curDialog->part()->info()->isDataExportSupported()
|
|
&& !d->curDialog->neverSaved() );
|
|
|
|
const bool printingActionsEnabled =
|
|
d->curDialog && d->curDialog->part()->info()->isPrintingSupported()
|
|
&& !d->curDialog->neverSaved();
|
|
d->action_project_print->setEnabled( printingActionsEnabled );
|
|
d->action_project_print_preview->setEnabled( printingActionsEnabled );
|
|
d->action_project_print_setup->setEnabled( printingActionsEnabled );
|
|
|
|
//EDIT MENU
|
|
|
|
if (d->action_edit_paste_special_data_table)
|
|
d->action_edit_paste_special_data_table->setEnabled(d->prj && !readOnly);
|
|
|
|
//! @todo "copy special" is currently enabled only for data view mode;
|
|
//! what about allowing it to enable in design view for "kexi/table" ?
|
|
if (d->curDialog && d->curDialog->currentViewMode()==Kexi::DataViewMode) {
|
|
KexiPart::Info *activePartInfo = d->curDialog->part()->info();
|
|
d->action_edit_copy_special_data_table->setEnabled(
|
|
activePartInfo ? activePartInfo->isDataExportSupported() : false );
|
|
}
|
|
else
|
|
d->action_edit_copy_special_data_table->setEnabled( false );
|
|
|
|
//VIEW MENU
|
|
if (d->action_view_nav)
|
|
d->action_view_nav->setEnabled(d->prj);
|
|
d->action_view_mainarea->setEnabled(d->prj);
|
|
if (d->action_view_propeditor)
|
|
d->action_view_propeditor->setEnabled(d->prj);
|
|
if (d->action_view_data_mode) {
|
|
d->action_view_data_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::DataViewMode) );
|
|
if (!d->action_view_data_mode->isEnabled())
|
|
d->action_view_data_mode->setChecked(false);
|
|
}
|
|
if (d->action_view_design_mode) {
|
|
d->action_view_design_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::DesignViewMode) );
|
|
if (!d->action_view_design_mode->isEnabled())
|
|
d->action_view_design_mode->setChecked(false);
|
|
}
|
|
if (d->action_view_text_mode) {
|
|
d->action_view_text_mode->setEnabled( have_dialog && d->curDialog->supportsViewMode(Kexi::TextViewMode) );
|
|
if (!d->action_view_text_mode->isEnabled())
|
|
d->action_view_text_mode->setChecked(false);
|
|
}
|
|
#ifndef KEXI_NO_CTXT_HELP
|
|
d->action_show_helper->setEnabled(d->prj);
|
|
#endif
|
|
|
|
//CREATE MENU
|
|
if (d->createMenu)
|
|
d->createMenu->setEnabled(d->prj);
|
|
|
|
// DATA MENU
|
|
//d->action_data_execute->setEnabled( d->curDialog && d->curDialog->part()->info()->isExecuteSupported() );
|
|
|
|
//TOOLS MENU
|
|
// "compact db" supported if there's no db or the current db supports compacting and is opened r/w:
|
|
d->action_tools_compact_database->setEnabled(
|
|
!d->prj || !readOnly && d->prj && d->prj->dbConnection()
|
|
&& (d->prj->dbConnection()->driver()->features() & KexiDB::Driver::CompactingDatabaseSupported) );
|
|
|
|
//WINDOW MENU
|
|
if (d->action_window_next) {
|
|
d->action_window_next->setEnabled(!m_pDocumentViews->isEmpty());
|
|
d->action_window_previous->setEnabled(!m_pDocumentViews->isEmpty());
|
|
}
|
|
|
|
//DOCKS
|
|
if (d->nav)
|
|
d->nav->setEnabled(d->prj);
|
|
if (d->propEditor)
|
|
d->propEditorTabWidget->setEnabled(d->prj);
|
|
}
|
|
|
|
void KexiMainWindowImpl::invalidateViewModeActions()
|
|
{
|
|
if (d->curDialog) {
|
|
//update toggle action
|
|
if (d->curDialog->currentViewMode()==Kexi::DataViewMode) {
|
|
if (d->action_view_data_mode)
|
|
d->action_view_data_mode->setChecked( true );
|
|
}
|
|
else if (d->curDialog->currentViewMode()==Kexi::DesignViewMode) {
|
|
if (d->action_view_design_mode)
|
|
d->action_view_design_mode->setChecked( true );
|
|
}
|
|
else if (d->curDialog->currentViewMode()==Kexi::TextViewMode) {
|
|
if (d->action_view_text_mode)
|
|
d->action_view_text_mode->setChecked( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::startup()
|
|
{
|
|
switch (Kexi::startupHandler().action()) {
|
|
case KexiStartupHandler::CreateBlankProject:
|
|
if (d->propEditor)
|
|
makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
|
|
return createBlankProject();
|
|
case KexiStartupHandler::CreateFromTemplate:
|
|
return createProjectFromTemplate(*Kexi::startupHandler().projectData());
|
|
case KexiStartupHandler::OpenProject:
|
|
return openProject(*Kexi::startupHandler().projectData());
|
|
case KexiStartupHandler::ImportProject:
|
|
return showProjectMigrationWizard(
|
|
Kexi::startupHandler().importActionData().mimeType,
|
|
Kexi::startupHandler().importActionData().fileName
|
|
);
|
|
default:;
|
|
if (d->propEditor)
|
|
makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static TQString internalReason(KexiDB::Object *obj)
|
|
{
|
|
const TQString &s = obj->errorMsg();
|
|
if (s.isEmpty())
|
|
return s;
|
|
return TQString("<br>(%1) ").arg(i18n("reason:")+" <i>"+s+"</i>");
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::openProject(const KexiProjectData& projectData)
|
|
{
|
|
KexiProjectData *newProjectData = new KexiProjectData(projectData);
|
|
// if (userMode()) {
|
|
//TODO: maybe also auto allow to open objects...
|
|
// return initUserModeMode(newProjectData);
|
|
// }
|
|
createKexiProject( newProjectData );
|
|
if (!newProjectData->connectionData()->savePassword
|
|
&& newProjectData->connectionData()->password.isEmpty()
|
|
&& newProjectData->connectionData()->fileName().isEmpty() //! @todo temp.: change this if there are file-based drivers requiring a password
|
|
)
|
|
{
|
|
//ask for password
|
|
KexiDBPasswordDialog pwdDlg(this, *newProjectData->connectionData(),
|
|
false /*!showDetailsButton*/);
|
|
if (TQDialog::Accepted!=pwdDlg.exec()) {
|
|
delete d->prj;
|
|
d->prj = 0;
|
|
return cancelled;
|
|
}
|
|
}
|
|
bool incompatibleWithKexi;
|
|
tristate res = d->prj->open(incompatibleWithKexi);
|
|
if (~res) {
|
|
delete d->prj;
|
|
d->prj = 0;
|
|
return cancelled;
|
|
}
|
|
else if (!res) {
|
|
delete d->prj;
|
|
d->prj = 0;
|
|
if (incompatibleWithKexi) {
|
|
if (KMessageBox::Yes == KMessageBox::questionYesNo(this,
|
|
i18n("<qt>Database project %1 does not appear to have been created using Kexi.<br><br>"
|
|
"Do you want to import it as a new Kexi project?</qt>").arg(projectData.infoString()),
|
|
0, KGuiItem(i18n("Import Database", "&Import..."), "database_import"),
|
|
KStdGuiItem::quit()))
|
|
{
|
|
const bool anotherProjectAlreadyOpened = d->prj;
|
|
tristate res = showProjectMigrationWizard("application/x-kexi-connectiondata",
|
|
projectData.databaseName(), projectData.constConnectionData());
|
|
|
|
if (!anotherProjectAlreadyOpened) //the project could have been opened within this instance
|
|
return res;
|
|
|
|
//always return cancelled because even if migration succeeded, new Kexi instance
|
|
//will be started if user wanted to open the imported db
|
|
return cancelled;
|
|
}
|
|
return cancelled;
|
|
}
|
|
return false;
|
|
}
|
|
initNavigator();
|
|
Kexi::recentProjects().addProjectData( newProjectData );
|
|
updateReadOnlyState();
|
|
invalidateActions();
|
|
// d->disableErrorMessages = true;
|
|
enableMessages( false );
|
|
|
|
TQTimer::singleShot(1, TQT_TQOBJECT(this), TQT_SLOT(slotAutoOpenObjectsLater()));
|
|
return true;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::createProjectFromTemplate(const KexiProjectData& projectData)
|
|
{
|
|
TQStringList mimetypes;
|
|
mimetypes.append( KexiDB::Driver::defaultFileBasedDriverMimeType() );
|
|
TQString fname;
|
|
const TQString startDir(":OpenExistingOrCreateNewProject"/*as in KexiNewProjectWizard*/);
|
|
const TQString caption( i18n("Select New Project's Location") );
|
|
|
|
while (true) {
|
|
#ifdef TQ_WS_WIN
|
|
//! @todo remove
|
|
TQString recentDir = TDEGlobalSettings::documentPath();
|
|
if (fname.isEmpty() && !projectData.constConnectionData()->dbFileName().isEmpty()) //propose filename from db template name
|
|
fname = KFileDialog::getStartURL(startDir, recentDir).path()
|
|
+ '/' + projectData.constConnectionData()->dbFileName();
|
|
fname = TQFileDialog::getSaveFileName(
|
|
KFileDialog::getStartURL(fname.isEmpty() ? startDir : fname, recentDir).path(),
|
|
KexiUtils::fileDialogFilterStrings(mimetypes, false),
|
|
this, "CreateProjectFromTemplate", caption);
|
|
if ( !fname.isEmpty() ) {
|
|
//save last visited path
|
|
KURL url;
|
|
url.setPath( fname );
|
|
if (url.isLocalFile())
|
|
TDERecentDirs::add(startDir, url.directory());
|
|
}
|
|
#else
|
|
Q_UNUSED(projectData);
|
|
if (fname.isEmpty() &&
|
|
!projectData.constConnectionData()->dbFileName().isEmpty())
|
|
{
|
|
//propose filename from db template name
|
|
fname = projectData.constConnectionData()->dbFileName();
|
|
}
|
|
const bool specialDir = fname.isEmpty();
|
|
kdDebug() << fname << "............." << endl;
|
|
KFileDialog dlg( specialDir ? startDir : TQString(),
|
|
mimetypes.join(" "), this, "filedialog", true);
|
|
if ( !specialDir )
|
|
dlg.setSelection( fname ); // may also be a filename
|
|
dlg.setOperationMode( KFileDialog::Saving );
|
|
dlg.setCaption( caption );
|
|
dlg.exec();
|
|
fname = dlg.selectedFile();
|
|
if (!fname.isEmpty())
|
|
TDERecentDocument::add(fname);
|
|
// fname = KFileDialog::getSaveFileName(fname.isEmpty() ? startDir : fname,
|
|
// mimetypes.join(" "), this, caption);
|
|
#endif
|
|
if ( fname.isEmpty() )
|
|
return cancelled;
|
|
if (KexiStartupFileDialog::askForOverwriting(fname, this))
|
|
break;
|
|
}
|
|
|
|
if (KexiUtils::CopySuccess != KexiUtils::copyFile(
|
|
projectData.constConnectionData()->fileName(), fname ))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return openProject(fname, 0, TQString(), projectData.autoopenObjects/*copy*/);
|
|
}
|
|
|
|
void KexiMainWindowImpl::updateReadOnlyState()
|
|
{
|
|
const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->isReadOnly();
|
|
d->statusBar->setReadOnlyFlag( readOnly );
|
|
if (d->nav)
|
|
d->nav->setReadOnly(readOnly);
|
|
// update "insert ....." actions for every part
|
|
TDEActionCollection *ac = actionCollection();
|
|
for (KexiPart::PartInfoListIterator it(*Kexi::partManager().partInfoList()); it.current(); ++it) {
|
|
TDEAction *a = ac->action( TQString(KexiPart::nameForCreateAction( *it.current() )).ascii() );
|
|
if (a)
|
|
a->setEnabled(!readOnly);
|
|
}
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotAutoOpenObjectsLater()
|
|
{
|
|
TQString not_found_msg;
|
|
bool openingCancelled;
|
|
//ok, now open "autoopen: objects
|
|
if (d->prj) {
|
|
for (TQValueList<KexiProjectData::ObjectInfo>::ConstIterator it =
|
|
d->prj->data()->autoopenObjects.constBegin();
|
|
it != d->prj->data()->autoopenObjects.constEnd(); ++it )
|
|
{
|
|
KexiProjectData::ObjectInfo info = *it;
|
|
KexiPart::Info *i = Kexi::partManager().infoForMimeType(
|
|
TQCString("kexi/")+info["type"].lower().latin1() );
|
|
if (!i) {
|
|
not_found_msg += "<li>";
|
|
if (!info["name"].isEmpty())
|
|
not_found_msg += (TQString("\"") + info["name"] + "\" - ");
|
|
if (info["action"]=="new")
|
|
not_found_msg += i18n("cannot create object - unknown object type \"%1\"")
|
|
.arg(info["type"]);
|
|
else
|
|
not_found_msg += i18n("unknown object type \"%1\"").arg(info["type"]);
|
|
not_found_msg += internalReason(&Kexi::partManager())+"<br></li>";
|
|
continue;
|
|
}
|
|
// * NEW
|
|
if (info["action"]=="new") {
|
|
if (!newObject( i, openingCancelled) && !openingCancelled) {
|
|
not_found_msg += "<li>";
|
|
not_found_msg += (i18n("cannot create object of type \"%1\"").arg(info["type"])+
|
|
internalReason(d->prj)+"<br></li>");
|
|
}
|
|
else
|
|
d->wasAutoOpen = true;
|
|
continue;
|
|
}
|
|
|
|
KexiPart::Item *item = d->prj->item(i, info["name"]);
|
|
|
|
if (!item) {
|
|
TQString taskName;
|
|
if (info["action"]=="print-preview")
|
|
taskName = i18n("making print preview for");
|
|
else if (info["action"]=="print")
|
|
taskName = i18n("printing");
|
|
else if (info["action"]=="execute")
|
|
taskName = i18n("\"executing object\" action", "executing");
|
|
else
|
|
taskName = i18n("opening");
|
|
|
|
not_found_msg += (TQString("<li>")+ taskName + " \"" + info["name"] + "\" - ");
|
|
if ("table"==info["type"].lower())
|
|
not_found_msg += i18n("table not found");
|
|
else if ("query"==info["type"].lower())
|
|
not_found_msg += i18n("query not found");
|
|
else if ("macro"==info["type"].lower())
|
|
not_found_msg += i18n("macro not found");
|
|
else if ("script"==info["type"].lower())
|
|
not_found_msg += i18n("script not found");
|
|
else
|
|
not_found_msg += i18n("object not found");
|
|
not_found_msg += (internalReason(d->prj)+"<br></li>");
|
|
continue;
|
|
}
|
|
// * EXECUTE, PRINT, PRINT PREVIEW
|
|
if (info["action"]=="execute") {
|
|
tristate res = executeItem(item);
|
|
if (false == res) {
|
|
not_found_msg += ( TQString("<li>\"")+ info["name"] + "\" - " + i18n("cannot execute object")+
|
|
internalReason(d->prj)+"<br></li>" );
|
|
}
|
|
continue;
|
|
}
|
|
else if (info["action"]=="print") {
|
|
tristate res = printItem(item);
|
|
if (false == res) {
|
|
not_found_msg += ( TQString("<li>\"")+ info["name"] + "\" - " + i18n("cannot print object")+
|
|
internalReason(d->prj)+"<br></li>" );
|
|
}
|
|
continue;
|
|
}
|
|
else if (info["action"]=="print-preview") {
|
|
tristate res = printPreviewForItem(item);
|
|
if (false == res) {
|
|
not_found_msg += ( TQString("<li>\"")+ info["name"] + "\" - " + i18n("cannot make print preview of object")+
|
|
internalReason(d->prj)+"<br></li>" );
|
|
}
|
|
continue;
|
|
}
|
|
|
|
int viewMode;
|
|
if (info["action"]=="open")
|
|
viewMode = Kexi::DataViewMode;
|
|
else if (info["action"]=="design")
|
|
viewMode = Kexi::DesignViewMode;
|
|
else if (info["action"]=="edittext")
|
|
viewMode = Kexi::TextViewMode;
|
|
else
|
|
continue; //sanity
|
|
|
|
TQString openObjectMessage;
|
|
if (!openObject(item, viewMode, openingCancelled, 0, &openObjectMessage)
|
|
&& (!openingCancelled || !openObjectMessage.isEmpty()))
|
|
{
|
|
not_found_msg += (TQString("<li>\"")+ info["name"] + "\" - ");
|
|
if (openObjectMessage.isEmpty())
|
|
not_found_msg += i18n("cannot open object");
|
|
else
|
|
not_found_msg += openObjectMessage;
|
|
not_found_msg += internalReason(d->prj) + "<br></li>";
|
|
continue;
|
|
}
|
|
else {
|
|
d->wasAutoOpen = true;
|
|
}
|
|
}
|
|
}
|
|
enableMessages( true );
|
|
// d->disableErrorMessages = false;
|
|
|
|
if (!not_found_msg.isEmpty())
|
|
showErrorMessage(i18n("You have requested selected objects to be automatically opened "
|
|
"or processed on startup. Several objects cannot be opened or processed."),
|
|
TQString("<ul>%1</ul>").arg(not_found_msg) );
|
|
|
|
d->updatePropEditorVisibility(d->curDialog ? d->curDialog->currentViewMode() : 0);
|
|
#if defined(KDOCKWIDGET_P)
|
|
if (d->propEditor) {
|
|
KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
if(ds)
|
|
ds->setSeparatorPosInPercent(d->config->readNumEntry("RightDockPosition", 80/* % */));
|
|
}
|
|
#endif
|
|
|
|
updateAppCaption();
|
|
|
|
// d->navToolWindow->wrapperWidget()->setFixedWidth(200);
|
|
//js TODO: make visible FOR OTHER MODES if needed
|
|
if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
|
|
//make docks visible again
|
|
if (!d->navToolWindow->wrapperWidget()->isVisible())
|
|
static_cast<KDockWidget*>(d->navToolWindow->wrapperWidget())->makeDockVisible();
|
|
// if (!d->propEditorToolWindow->wrapperWidget()->isVisible())
|
|
// static_cast<KDockWidget*>(d->propEditorToolWindow->wrapperWidget())->makeDockVisible();
|
|
}
|
|
|
|
// if (!d->prj->data()->autoopenObjects.isEmpty())
|
|
d->restoreNavigatorWidth();
|
|
|
|
#ifndef PROPEDITOR_VISIBILITY_CHANGES
|
|
// KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
|
|
// KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
// const int pos = ds->separatorPos();
|
|
|
|
//if (!d->curDialog || d->curDialog->currentViewMode()==Kexi::DataViewMode)
|
|
// d->propEditorToolWindow->hide();
|
|
|
|
// ds->setSeparatorPos( pos, true );
|
|
#endif
|
|
if (d->nav) {
|
|
d->nav->updateGeometry();
|
|
}
|
|
tqApp->processEvents();
|
|
emit projectOpened();
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::closeProject()
|
|
{
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
if (d->pendingDialogsExist()) {
|
|
kdDebug() << "KexiMainWindowImpl::closeProject() pendingDialogsExist..." << endl;
|
|
d->actionToExecuteWhenPendingJobsAreFinished = Private::CloseProjectAction;
|
|
return cancelled;
|
|
}
|
|
#endif
|
|
|
|
//only save nav. visibility setting is project is opened
|
|
d->saveSettingsForShowProjectNavigator = d->prj && d->isProjectNavigatorVisible;
|
|
|
|
if (!d->prj)
|
|
return true;
|
|
|
|
{
|
|
// make sure the project can be closed
|
|
bool cancel = false;
|
|
emit acceptProjectClosingRequested(cancel);
|
|
if (cancel)
|
|
return cancelled;
|
|
}
|
|
|
|
d->dialogExistedBeforeCloseProject = !d->curDialog.isNull();
|
|
|
|
#if defined(KDOCKWIDGET_P)
|
|
//remember docks position - will be used on storeSettings()
|
|
if (d->propEditor) {
|
|
KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
if (ds)
|
|
d->propEditorDockSeparatorPos = ds->separatorPosInPercent();
|
|
}
|
|
if (d->nav) {
|
|
// makeDockInvisible( manager()->findWidgetParentDock(d->propEditor) );
|
|
|
|
if (d->propEditor) {
|
|
if (d->openedDialogsCount() == 0)
|
|
makeWidgetDockVisible(d->propEditorTabWidget);
|
|
KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
if(ds)
|
|
ds->setSeparatorPosInPercent(80);
|
|
}
|
|
|
|
KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
int dwWidth = dw->width();
|
|
if (ds) {
|
|
if (d->openedDialogsCount()!=0 && d->propEditorTabWidget && d->propEditorTabWidget->isVisible())
|
|
d->navDockSeparatorPos = ds->separatorPosInPercent();
|
|
else
|
|
d->navDockSeparatorPos = (100 * dwWidth) / width();
|
|
|
|
// int navDockSeparatorPosWithAutoOpen = (100 * dw->width()) / width() + 4;
|
|
// d->navDockSeparatorPos = (100 * dw->width()) / width() + 1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//close each window, optionally asking if user wants to close (if data changed)
|
|
while (!d->curDialog.isNull()) {
|
|
tristate res = closeDialog( d->curDialog );
|
|
if (!res || ~res)
|
|
return res;
|
|
}
|
|
|
|
// now we will close for sure
|
|
emit beforeProjectClosing();
|
|
|
|
if (!d->prj->closeConnection())
|
|
return false;
|
|
|
|
if(d->nav)
|
|
{
|
|
d->navWasVisibleBeforeProjectClosing = manager()->findWidgetParentDock(d->nav)->isVisible();
|
|
d->nav->clear();
|
|
#if 0 //do not confuse users
|
|
d->navToolWindow->hide();
|
|
#endif
|
|
}
|
|
|
|
if (d->propEditor)
|
|
makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
|
|
|
|
// if(d->propEditorToolWindow)
|
|
// d->propEditorToolWindow->hide();
|
|
|
|
d->clearDialogs(); //sanity!
|
|
delete d->prj;
|
|
d->prj=0;
|
|
|
|
// Kexi::partManager().unloadAllParts();
|
|
|
|
updateReadOnlyState();
|
|
invalidateActions();
|
|
// if (!userMode())
|
|
updateAppCaption();
|
|
|
|
emit projectClosed();
|
|
return true;
|
|
}
|
|
|
|
void KexiMainWindowImpl::initContextHelp() {
|
|
#ifndef KEXI_NO_CTXT_HELP
|
|
d->ctxHelp=new KexiContextHelp(this,this);
|
|
/*todo
|
|
d->ctxHelp->setContextHelp(i18n("Welcome"),i18n("The <B>KEXI team</B> wishes you a lot of productive work, "
|
|
"with this product. <BR><HR><BR>If you have found a <B>bug</B> or have a <B>feature</B> request, please don't "
|
|
"hesitate to report it at our <A href=\"http://www.kexi-project.org/cgi-bin/bug.pl\"> issue "
|
|
"tracking system </A>.<BR><HR><BR>If you would like to <B>join</B> our effort, the <B>development</B> documentation "
|
|
"at <A href=\"http://www.kexi-project.org\">www.kexi-project.org</A> is a good starting point."),0);
|
|
*/
|
|
addToolWindow(d->ctxHelp,KDockWidget::DockBottom | KDockWidget::DockLeft,getMainDockWidget(),20);
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::initNavigator()
|
|
{
|
|
if (!d->isProjectNavigatorVisible)
|
|
return;
|
|
|
|
if(!d->nav)
|
|
{
|
|
d->nav = new KexiBrowser(this, this);
|
|
d->nav->installEventFilter(TQT_TQOBJECT(this));
|
|
d->navToolWindow = addToolWindow(d->nav, KDockWidget::DockLeft, getMainDockWidget(), 20/*, lv, 35, "2"*/);
|
|
// d->navToolWindow->hide();
|
|
|
|
connect(d->nav,TQT_SIGNAL(openItem(KexiPart::Item*,int)),this,TQT_SLOT(openObject(KexiPart::Item*,int)));
|
|
connect(d->nav,TQT_SIGNAL(openOrActivateItem(KexiPart::Item*,int)),
|
|
this,TQT_SLOT(openObjectFromNavigator(KexiPart::Item*,int)));
|
|
connect(d->nav,TQT_SIGNAL(newItem( KexiPart::Info* )),
|
|
this,TQT_SLOT(newObject(KexiPart::Info*)));
|
|
connect(d->nav,TQT_SIGNAL(removeItem(KexiPart::Item*)),
|
|
this,TQT_SLOT(removeObject(KexiPart::Item*)));
|
|
connect(d->nav,TQT_SIGNAL(renameItem(KexiPart::Item*,const TQString&, bool&)),
|
|
this,TQT_SLOT(renameObject(KexiPart::Item*,const TQString&, bool&)));
|
|
connect(d->nav,TQT_SIGNAL(executeItem(KexiPart::Item*)),
|
|
this,TQT_SLOT(executeItem(KexiPart::Item*)));
|
|
connect(d->nav,TQT_SIGNAL(exportItemAsDataTable(KexiPart::Item*)),
|
|
this,TQT_SLOT(exportItemAsDataTable(KexiPart::Item*)));
|
|
connect(d->nav,TQT_SIGNAL(printItem( KexiPart::Item* )),
|
|
this,TQT_SLOT(printItem(KexiPart::Item*)));
|
|
connect(d->nav,TQT_SIGNAL(pageSetupForItem( KexiPart::Item*)),
|
|
this,TQT_SLOT(showPageSetupForItem(KexiPart::Item*)));
|
|
if (d->prj) {//connect to the project
|
|
connect(d->prj, TQT_SIGNAL(itemRemoved(const KexiPart::Item&)),
|
|
d->nav, TQT_SLOT(slotRemoveItem(const KexiPart::Item&)));
|
|
}
|
|
connect(d->nav,TQT_SIGNAL(selectionChanged(KexiPart::Item*)),
|
|
this,TQT_SLOT(slotPartItemSelectedInNavigator(KexiPart::Item*)));
|
|
|
|
// d->restoreNavigatorWidth();
|
|
}
|
|
if(d->prj->isConnected()) {
|
|
TQString partManagerErrorMessages;
|
|
d->nav->setProject( d->prj, TQString()/*all mimetypes*/, &partManagerErrorMessages );
|
|
if (!partManagerErrorMessages.isEmpty()) {
|
|
showWarningContinueMessage(partManagerErrorMessages, TQString(),
|
|
"dontShowWarningsRelatedToPluginsLoading");
|
|
}
|
|
}
|
|
connect(d->prj, TQT_SIGNAL(newItemStored(KexiPart::Item&)), d->nav, TQT_SLOT(addItem(KexiPart::Item&)));
|
|
d->nav->setFocus();
|
|
|
|
if (d->forceShowProjectNavigatorOnCreation) {
|
|
slotViewNavigator();
|
|
d->forceShowProjectNavigatorOnCreation = false;
|
|
}
|
|
else if (d->forceHideProjectNavigatorOnCreation) {
|
|
d->navToolWindow->hide();
|
|
// makeDockInvisible( manager()->findWidgetParentDock(d->nav) );
|
|
d->forceHideProjectNavigatorOnCreation = false;
|
|
}
|
|
|
|
invalidateActions();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotLastActions()
|
|
{
|
|
#if defined(KDOCKWIDGET_P)
|
|
if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
|
|
// KDockWidget *dw = (KDockWidget *)d->propEditor->parentWidget();
|
|
//KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
// Q_UNUSED(ds);
|
|
//1 ds->resize(ds->width()*3, ds->height());
|
|
//1 ds->setSeparatorPos(30, true);
|
|
//1 ds->setForcedFixedWidth( dw, 200 );
|
|
}
|
|
#endif
|
|
#ifdef TQ_WS_WIN
|
|
showMaximized();//js: workaround for not yet completed layout settings storage on win32
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::initPropertyEditor()
|
|
{
|
|
if (!d->propEditor) {
|
|
//TODO: FIX LAYOUT PROBLEMS
|
|
d->propEditorTabWidget = new KTabWidget(this);
|
|
d->propEditorTabWidget->hide();
|
|
d->propEditor = new KexiPropertyEditorView(this, d->propEditorTabWidget);
|
|
d->propEditorTabWidget->setCaption(d->propEditor->caption());
|
|
d->propEditorTabWidget->addTab(d->propEditor, i18n("Properties"));
|
|
d->propEditor->installEventFilter(this);
|
|
d->propEditorToolWindow = addToolWindow(d->propEditorTabWidget,
|
|
KDockWidget::DockRight, getMainDockWidget(), 20);
|
|
|
|
d->config->setGroup("PropertyEditor");
|
|
int size = d->config->readNumEntry("FontSize", -1);
|
|
TQFont f( Kexi::smallFont() );
|
|
if (size>0)
|
|
f.setPixelSize( size );
|
|
d->propEditorTabWidget->setFont(f);
|
|
|
|
if (mdiMode()==KMdi::ChildframeMode || mdiMode()==KMdi::TabPageMode) {
|
|
KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget();
|
|
#if defined(KDOCKWIDGET_P)
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
// ds->setKeepSize(true);
|
|
makeWidgetDockVisible(d->propEditorTabWidget);
|
|
// ds->show();
|
|
// ds->resize(400, ds->height());
|
|
// ds->setSeparatorPos(400, true);
|
|
// ds->setForcedFixedWidth( dw, 400 );
|
|
// ds->setSeparatorPos(600, true);
|
|
|
|
|
|
d->config->setGroup("MainWindow");
|
|
ds->setSeparatorPosInPercent(d->config->readNumEntry("RightDockPosition", 80/* % */));
|
|
// makeDockInvisible( manager()->findWidgetParentDock(d->propEditor) );
|
|
|
|
// ds->setForcedFixedWidth( dw, d->config->readNumEntry("RightDockPosition", 80) );
|
|
// ds->resize(400, ds->height());
|
|
// dw->resize(400, dw->height());
|
|
#endif
|
|
|
|
//1 dw->setMinimumWidth(200);
|
|
|
|
// ds->setSeparatorPos(d->propEditor->sizeHint().width(), true);
|
|
|
|
//heh, this is for IDEAl only, I suppose?
|
|
//js if (m_rightContainer) {
|
|
//js m_rightContainer->setForcedFixedWidth( 400 );
|
|
//js }
|
|
}
|
|
|
|
// int w = d->propEditor->width();
|
|
/* KMdiToolViewAccessor *tmp=createToolWindow();
|
|
tmp->setWidgetToWrap(d->propEditor);
|
|
d->propEditor->show(); // I'm not sure, if this is a bug in kdockwidget, which I would better fix there
|
|
tmp->show(KDockWidget::DockRight,getMainDockWidget(),20);
|
|
*/
|
|
}
|
|
// makeDockInvisible(manager()->findWidgetParentDock(d->propEditorTabWidget));
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotPartLoaded(KexiPart::Part* p)
|
|
{
|
|
if (!p)
|
|
return;
|
|
connect(p, TQT_SIGNAL(newObjectRequest(KexiPart::Info*)),
|
|
TQT_TQOBJECT(this), TQT_SLOT(newObject(KexiPart::Info*)));
|
|
p->createGUIClients(this);
|
|
}
|
|
|
|
//! internal
|
|
void KexiMainWindowImpl::slotCaptionForCurrentMDIChild(bool childrenMaximized)
|
|
{
|
|
//js todo: allow to set custom "static" app caption
|
|
|
|
KMdiChildView *view = 0L;
|
|
if (!d->curDialog)
|
|
view = 0;
|
|
else if (d->curDialog->isAttached()) {
|
|
view = d->curDialog;
|
|
} else {
|
|
//current dialog isn't attached! - find top level child
|
|
if (m_pMdi->topChild()) {
|
|
view = m_pMdi->topChild()->m_pClient;
|
|
childrenMaximized = view->mdiParent()->state()==KMdiChildFrm::Maximized;
|
|
}
|
|
else
|
|
view = 0;
|
|
}
|
|
|
|
if (childrenMaximized && view) {
|
|
setCaption( d->curDialog->caption()
|
|
+ (d->appCaptionPrefix.isEmpty() ? TQString() : (TQString::fromLatin1(" - ") + d->appCaptionPrefix)) );
|
|
}
|
|
else {
|
|
setCaption( (d->appCaptionPrefix.isEmpty() ? TQString() : (d->appCaptionPrefix + TQString::fromLatin1(" - ")))
|
|
+ d->origAppCaption );
|
|
}
|
|
}
|
|
|
|
void KexiMainWindowImpl::updateAppCaption()
|
|
{
|
|
//js todo: allow to set custom "static" app caption
|
|
|
|
d->appCaptionPrefix = "";
|
|
if (d->prj && d->prj->data()) {//add project name
|
|
d->appCaptionPrefix = d->prj->data()->caption();
|
|
if (d->appCaptionPrefix.isEmpty())
|
|
d->appCaptionPrefix = d->prj->data()->databaseName();
|
|
}
|
|
// if (!d->appCaptionPrefix.isEmpty())
|
|
// d->appCaptionPrefix = d->appCaptionPrefix;
|
|
|
|
bool max = false;
|
|
if (d->curDialog && d->curDialog->mdiParent())
|
|
max = d->curDialog->mdiParent()->state()==KMdiChildFrm::Maximized;
|
|
|
|
slotCaptionForCurrentMDIChild(max);
|
|
/*
|
|
KMdiChildView *view;
|
|
if (!d->curDialog)
|
|
view = 0;
|
|
else if (d->curDialog->isAttached()) {
|
|
view = d->curDialog;
|
|
} else {
|
|
//current dialog isn't attached! - find top level child
|
|
if (m_pMdi->topChild()) {
|
|
view = m_pMdi->topChild()->m_pClient;
|
|
}
|
|
else
|
|
view = 0;
|
|
}
|
|
|
|
kApp->setCaption( d->appCaption );
|
|
if (view && view->mdiParent()->state()==KMdiChildFrm::Maximized) {
|
|
setCaption( view->caption() );
|
|
}
|
|
else {
|
|
setCaption( d->appCaption );
|
|
}*/
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotNoMaximizedChildFrmLeft(KMdiChildFrm*)
|
|
{
|
|
slotCaptionForCurrentMDIChild(false);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotLastChildViewClosed() //slotLastChildFrmClosed()
|
|
{
|
|
if (m_pDocumentViews->count()>0) //a fix for KMDI bug (will be fixed in KDE 3.4)
|
|
return;
|
|
|
|
slotCaptionForCurrentMDIChild(false);
|
|
activeWindowChanged(0);
|
|
|
|
//js: too WEIRD if (d->propEditor)
|
|
//js: too WEIRD makeDockInvisible( manager()->findWidgetParentDock(d->propEditorTabWidget) );
|
|
// if (d->propEditorToolWindow)
|
|
// d->propEditorToolWindow->hide();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotChildViewIsDetachedNow(TQWidget*)
|
|
{
|
|
slotCaptionForCurrentMDIChild(false);
|
|
}
|
|
|
|
/*void
|
|
KexiMainWindowImpl::closeEvent(TQCloseEvent *ev)
|
|
{
|
|
storeSettings();
|
|
|
|
bool cancelled = false;
|
|
if (!closeProject(cancelled)) {
|
|
//todo: error message
|
|
return;
|
|
}
|
|
if (cancelled) {
|
|
ev->ignore();
|
|
return;
|
|
}
|
|
|
|
ev->accept();
|
|
}*/
|
|
|
|
bool
|
|
KexiMainWindowImpl::queryClose()
|
|
{
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
if (d->pendingDialogsExist()) {
|
|
kdDebug() << "KexiMainWindowImpl::queryClose() pendingDialogsExist..." << endl;
|
|
d->actionToExecuteWhenPendingJobsAreFinished = Private::QuitAction;
|
|
return false;
|
|
}
|
|
#endif
|
|
// storeSettings();
|
|
const tristate res = closeProject();
|
|
if (~res)
|
|
return false;
|
|
|
|
if (res==true)
|
|
storeSettings();
|
|
|
|
return ! ~res;
|
|
}
|
|
|
|
bool
|
|
KexiMainWindowImpl::queryExit()
|
|
{
|
|
// storeSettings();
|
|
return true;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::restoreSettings()
|
|
{
|
|
d->config->setGroup("MainWindow");
|
|
|
|
// Saved settings
|
|
applyMainWindowSettings( d->config, "MainWindow" );
|
|
|
|
//small hack - set the default -- bottom
|
|
// d->config->setGroup(TQString(name()) + " KMdiTaskBar Toolbar style");
|
|
d->config->setGroup("MainWindow Toolbar KMdiTaskBar");
|
|
const bool tbe = d->config->readEntry("Position").isEmpty();
|
|
if (tbe || d->config->readEntry("Position")=="Bottom") {
|
|
if (tbe)
|
|
d->config->writeEntry("Position","Bottom");
|
|
moveDockWindow(m_pTaskBar, DockBottom);
|
|
}
|
|
|
|
d->config->setGroup("MainWindow");
|
|
int mdimode = d->config->readNumEntry("MDIMode", -1);//KMdi::TabPageMode);
|
|
|
|
const bool showProjectNavigator = d->config->readBoolEntry("ShowProjectNavigator", true);
|
|
|
|
switch(mdimode)
|
|
{
|
|
/* case KMdi::ToplevelMode:
|
|
switchToToplevelMode();
|
|
m_pTaskBar->switchOn(true);
|
|
break;*/
|
|
case KMdi::ChildframeMode:
|
|
switchToChildframeMode(false);
|
|
m_pTaskBar->switchOn(true);
|
|
|
|
// restore a possible maximized Childframe mode,
|
|
// will be used in KexiMainWindowImpl::addWindow()
|
|
d->maximizeFirstOpenedChildFrm = d->config->readBoolEntry("maximized childframes", true);
|
|
setEnableMaximizedChildFrmMode(d->maximizeFirstOpenedChildFrm);
|
|
|
|
if (!showProjectNavigator) {
|
|
//it's visible by default but we want to hide it on navigator creation
|
|
d->forceHideProjectNavigatorOnCreation = true;
|
|
}
|
|
|
|
break;
|
|
|
|
#define DEFAULT_MDI_MODE KMdi::IDEAlMode
|
|
|
|
case DEFAULT_MDI_MODE:
|
|
default:
|
|
switchToIDEAlMode(false);
|
|
if (showProjectNavigator) {
|
|
//it's invisible by default but we want to show it on navigator creation
|
|
d->forceShowProjectNavigatorOnCreation = true;
|
|
}
|
|
break;
|
|
/* case KMdi::TabPageMode:
|
|
switchToTabPageMode();
|
|
break;
|
|
*/
|
|
}
|
|
|
|
#if 0
|
|
if ( !initialGeometrySet() ) {
|
|
// Default size
|
|
// int restoredWidth, restoredHeight;
|
|
int scnum = TQApplication::desktop()->screenNumber(parentWidget());
|
|
TQRect desk = TQApplication::desktop()->screenGeometry(scnum);
|
|
//#if KDE_IS_VERSION(3,1,90)
|
|
// restoredWidth = TDEGlobalSettings::screenGeometry(scnum).width();
|
|
// restoredHeight = TDEGlobalSettings::screenGeometry(scnum).height();
|
|
//#else
|
|
// restoredWidth = TQApplication::desktop()->width();
|
|
// restoredHeight = TQApplication::desktop()->height();
|
|
//#endif
|
|
/* if (restoredWidth > 1100) {// very big desktop ?
|
|
restoredWidth = 1000;
|
|
restoredHeight = 800;
|
|
}
|
|
if (restoredWidth > 850) {// big desktop ?
|
|
restoredWidth = 800;
|
|
restoredHeight = 600;
|
|
}
|
|
else {// small (800x600, 640x480) desktop
|
|
restoredWidth = TQMIN( restoredWidth, 600 );
|
|
restoredHeight = TQMIN( restoredHeight, 400 );
|
|
}*/
|
|
|
|
config->setGroup("MainWindow");
|
|
TQSize s ( config->readNumEntry( TQString::fromLatin1("Width %1").arg(desk.width()), 700 ),
|
|
config->readNumEntry( TQString::fromLatin1("Height %1").arg(desk.height()), 480 ) );
|
|
resize (kMin (s.width(), desk.width()), kMin(s.height(), desk.height()));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::storeSettings()
|
|
{
|
|
kdDebug() << "KexiMainWindowImpl::storeSettings()" << endl;
|
|
|
|
// saveWindowSize( d->config ); //instance()->config() );
|
|
saveMainWindowSettings( d->config, "MainWindow" );
|
|
d->config->setGroup("MainWindow");
|
|
KMdi::MdiMode modeToSave = mdiMode();
|
|
if (d->mdiModeToSwitchAfterRestart!=(KMdi::MdiMode)0)
|
|
modeToSave = d->mdiModeToSwitchAfterRestart;
|
|
if (modeToSave == DEFAULT_MDI_MODE)
|
|
d->config->deleteEntry("MDIMode");
|
|
else
|
|
d->config->writeEntry("MDIMode", modeToSave);
|
|
d->config->writeEntry("maximized childframes", isInMaximizedChildFrmMode());
|
|
|
|
// if (manager()->findWidgetParentDock(d->nav)->isVisible())
|
|
if (d->saveSettingsForShowProjectNavigator) {
|
|
if (d->navWasVisibleBeforeProjectClosing)
|
|
d->config->deleteEntry("ShowProjectNavigator");
|
|
else
|
|
d->config->writeEntry("ShowProjectNavigator", false);
|
|
}
|
|
|
|
if (modeToSave==KMdi::ChildframeMode || modeToSave==KMdi::TabPageMode) {
|
|
if (d->propEditor && d->propEditorDockSeparatorPos >= 0 && d->propEditorDockSeparatorPos <= 100) {
|
|
d->config->setGroup("MainWindow");
|
|
d->config->writeEntry("RightDockPosition", d->propEditorDockSeparatorPos);
|
|
}
|
|
else
|
|
d->propEditorDockSeparatorPos = 80;
|
|
if (d->nav && d->navDockSeparatorPos >= 0 && d->navDockSeparatorPos <= 100) {
|
|
d->config->setGroup("MainWindow");
|
|
//KDockWidget *dw = (KDockWidget *)d->nav->parentWidget();
|
|
//int w = dw->width();
|
|
//int ww = width();
|
|
//int d1 = (100 * dw->width()) / width() + 1;
|
|
//KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
//int d2 = ds->separatorPosInPercent();
|
|
if (d->wasAutoOpen && d->dialogExistedBeforeCloseProject) {
|
|
#ifdef TQ_WS_WIN
|
|
d->config->writeEntry("LeftDockPositionWithAutoOpen",
|
|
d->navDockSeparatorPos);
|
|
#endif
|
|
// d->config->writeEntry("LeftDockPosition", dw->width());
|
|
// d->config->writeEntry("LeftDockPosition", d->nav->width());
|
|
} else {
|
|
#ifdef TQ_WS_WIN
|
|
if (d->dialogExistedBeforeCloseProject)
|
|
d->config->writeEntry("LeftDockPosition", d->navDockSeparatorPos);
|
|
else
|
|
d->config->writeEntry("LeftDockPosition", tqRound(double(d->navDockSeparatorPos) / 0.77
|
|
/ (double(d->propEditorDockSeparatorPos) / 80) ));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
if (d->propEditor) {
|
|
d->config->setGroup("PropertyEditor");
|
|
d->config->writeEntry("FontSize", d->propEditorTabWidget->font().pixelSize());
|
|
}
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::restoreWindowConfiguration(TDEConfig *config)
|
|
{
|
|
kdDebug()<<"preparing session restoring"<<endl;
|
|
|
|
config->setGroup("MainWindow");
|
|
|
|
TQString dockGrp;
|
|
|
|
if (kapp->isRestored())
|
|
dockGrp=config->group()+"-Docking";
|
|
else
|
|
dockGrp="MainWindow0-Docking";
|
|
|
|
if (config->hasGroup(dockGrp))
|
|
readDockConfig(config,dockGrp);
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::storeWindowConfiguration(TDEConfig *config)
|
|
{
|
|
kdDebug()<<"preparing session saving"<<endl;
|
|
config->setGroup("MainWindow");
|
|
TQString dockGrp;
|
|
|
|
#if KDE_IS_VERSION(3,1,9) && !defined(TQ_WS_WIN)
|
|
if (kapp->sessionSaving())
|
|
dockGrp=config->group()+"-Docking";
|
|
else
|
|
#endif
|
|
dockGrp="MainWindow0-Docking";
|
|
|
|
kdDebug()<<"Before write dock config"<<endl;
|
|
writeDockConfig(config,dockGrp);
|
|
kdDebug()<<"After write dock config"<<endl;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::readProperties(TDEConfig *config) {
|
|
restoreWindowConfiguration(config);
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::saveProperties(TDEConfig *config)
|
|
{
|
|
storeWindowConfiguration(config);
|
|
// m_docManager->saveDocumentList (config);
|
|
// m_projectManager->saveProjectList (config);
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::saveGlobalProperties( TDEConfig* sessionConfig ) {
|
|
storeWindowConfiguration(sessionConfig);
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::registerChild(KexiDialogBase *dlg)
|
|
{
|
|
kdDebug() << "KexiMainWindowImpl::registerChild()" << endl;
|
|
connect(dlg, TQT_SIGNAL(activated(KMdiChildView *)),
|
|
TQT_TQOBJECT(this), TQT_SLOT(activeWindowChanged(KMdiChildView *)));
|
|
connect(dlg, TQT_SIGNAL(dirtyChanged(KexiDialogBase*)),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotDirtyFlagChanged(KexiDialogBase*)));
|
|
|
|
// connect(dlg, TQT_SIGNAL(childWindowCloseRequest(KMdiChildView *)), TQT_TQOBJECT(this), TQT_SLOT(childClosed(KMdiChildView *)));
|
|
if(dlg->id() != -1) {
|
|
d->insertDialog(dlg);
|
|
}
|
|
kdDebug() << "KexiMainWindowImpl::registerChild() ID = " << dlg->id() << endl;
|
|
|
|
if (m_mdiMode==KMdi::ToplevelMode || m_mdiMode==KMdi::ChildframeMode) {//tdemdi fix
|
|
//js TODO: check if taskbar is switched in menu
|
|
if (m_pTaskBar && !m_pTaskBar->isSwitchedOn())
|
|
m_pTaskBar->switchOn(true);
|
|
}
|
|
//KMdiChildFrm *frm = dlg->mdiParent();
|
|
//if (frm) {
|
|
// dlg->setMargin(20);
|
|
//dlg->setLineWidth(20);
|
|
//}
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::updateDialogViewGUIClient(KXMLGUIClient *viewClient)
|
|
{
|
|
if (viewClient!=d->curDialogViewGUIClient) {
|
|
//view clients differ
|
|
kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old view gui client:"
|
|
<<(d->curDialogViewGUIClient ? d->curDialogViewGUIClient->xmlFile() : "")
|
|
<<" new view gui client: "<<( viewClient ? viewClient->xmlFile() : "") <<endl;
|
|
if (d->curDialogViewGUIClient) {
|
|
guiFactory()->removeClient(d->curDialogViewGUIClient);
|
|
}
|
|
if (viewClient) {
|
|
if (d->closedDialogViewGUIClient) {
|
|
//ooh, there is a client which dialog is already closed -- BUT it is the same client as our
|
|
//so: give up
|
|
}
|
|
else {
|
|
guiFactory()->addClient(viewClient);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KexiMainWindowImpl::updateCustomPropertyPanelTabs(KexiDialogBase *prevDialog, int prevViewMode)
|
|
{
|
|
updateCustomPropertyPanelTabs(
|
|
prevDialog ? prevDialog->part() : 0,
|
|
prevDialog ? prevDialog->currentViewMode() : prevViewMode,
|
|
d->curDialog ? d->curDialog->part() : 0,
|
|
d->curDialog ? d->curDialog->currentViewMode() : Kexi::NoViewMode
|
|
);
|
|
}
|
|
|
|
void KexiMainWindowImpl::updateCustomPropertyPanelTabs(
|
|
KexiPart::Part *prevDialogPart, int prevViewMode, KexiPart::Part *curDialogPart, int curViewMode )
|
|
{
|
|
if (!d->propEditorTabWidget)
|
|
return;
|
|
|
|
if (!curDialogPart
|
|
|| (/*prevDialogPart &&*/ curDialogPart
|
|
&& (prevDialogPart!=curDialogPart || prevViewMode!=curViewMode)
|
|
))
|
|
{
|
|
if (d->partForPreviouslySetupPropertyPanelTabs) {
|
|
//remember current page number for this part
|
|
if (prevViewMode==Kexi::DesignViewMode &&
|
|
((KexiPart::Part*)d->partForPreviouslySetupPropertyPanelTabs != curDialogPart) //part changed
|
|
|| curViewMode!=Kexi::DesignViewMode) //..or switching to other view mode
|
|
{
|
|
d->recentlySelectedPropertyPanelPages.insert( d->partForPreviouslySetupPropertyPanelTabs,
|
|
d->propEditorTabWidget->currentPageIndex() );
|
|
}
|
|
}
|
|
|
|
//delete old custom tabs (other than 'property' tab)
|
|
const uint count = d->propEditorTabWidget->count();
|
|
for (uint i=1; i < count; i++)
|
|
d->propEditorTabWidget->removePage( d->propEditorTabWidget->page(1) );
|
|
}
|
|
|
|
//don't change anything if part is not switched nor view mode changed
|
|
if ((!prevDialogPart && !curDialogPart)
|
|
|| (prevDialogPart == curDialogPart && prevViewMode==curViewMode)
|
|
|| (curDialogPart && curViewMode!=Kexi::DesignViewMode))
|
|
{
|
|
//new part for 'previously setup tabs'
|
|
d->partForPreviouslySetupPropertyPanelTabs = curDialogPart;
|
|
return;
|
|
}
|
|
|
|
if (curDialogPart) {
|
|
//recreate custom tabs
|
|
curDialogPart->setupCustomPropertyPanelTabs(d->propEditorTabWidget, this);
|
|
|
|
//restore current page number for this part
|
|
if (d->recentlySelectedPropertyPanelPages.contains( curDialogPart )) {
|
|
d->propEditorTabWidget->setCurrentPage(
|
|
d->recentlySelectedPropertyPanelPages[ curDialogPart ]
|
|
);
|
|
}
|
|
}
|
|
|
|
//new part for 'previously setup tabs'
|
|
d->partForPreviouslySetupPropertyPanelTabs = curDialogPart;
|
|
}
|
|
|
|
void KexiMainWindowImpl::activeWindowChanged(KMdiChildView *v)
|
|
{
|
|
KexiDialogBase *dlg = static_cast<KexiDialogBase *>(v);
|
|
kdDebug() << "KexiMainWindowImpl::activeWindowChanged() to = " << (dlg ? dlg->caption() : "<none>") << endl;
|
|
|
|
KXMLGUIClient *client=0; //common for all views
|
|
KXMLGUIClient *viewClient=0; //specific for current dialog's view
|
|
KexiDialogBase* prevDialog = d->curDialog;
|
|
|
|
if (!dlg)
|
|
client=0;
|
|
else if ( dlg->isRegistered()) {
|
|
// client=dlg->guiClient();
|
|
client=dlg->commonGUIClient();
|
|
viewClient=dlg->guiClient();
|
|
if (d->closedDialogGUIClient) {
|
|
if (client!=d->closedDialogGUIClient) {
|
|
//ooh, there is a client which dialog is already closed -- and we don't want it
|
|
guiFactory()->removeClient(d->closedDialogGUIClient);
|
|
d->closedDialogGUIClient=0;
|
|
}
|
|
}
|
|
if (d->closedDialogViewGUIClient) {
|
|
if (viewClient!=d->closedDialogViewGUIClient) {
|
|
//ooh, there is a client which dialog is already closed -- and we don't want it
|
|
guiFactory()->removeClient(d->closedDialogViewGUIClient);
|
|
d->closedDialogViewGUIClient=0;
|
|
}
|
|
}
|
|
if (client!=d->curDialogGUIClient) {
|
|
//clients differ
|
|
kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old gui client:"
|
|
<<(d->curDialogGUIClient ? d->curDialogGUIClient->xmlFile() : "")
|
|
<<" new gui client: "<<( client ? client->xmlFile() : "") <<endl;
|
|
if (d->curDialogGUIClient) {
|
|
guiFactory()->removeClient(d->curDialogGUIClient);
|
|
d->curDialog->detachFromGUIClient();
|
|
}
|
|
if (client) {
|
|
if (d->closedDialogGUIClient) {
|
|
//ooh, there is a client which dialog is already closed -- BUT it is the same client as our
|
|
//so: give up
|
|
}
|
|
else {
|
|
guiFactory()->addClient(client);
|
|
}
|
|
dlg->attachToGUIClient();
|
|
}
|
|
} else {
|
|
//clients are the same
|
|
if ((KexiDialogBase*)d->curDialog!=dlg) {
|
|
if (d->curDialog)
|
|
d->curDialog->detachFromGUIClient();
|
|
if (dlg)
|
|
dlg->attachToGUIClient();
|
|
}
|
|
}
|
|
updateDialogViewGUIClient(viewClient);
|
|
/* if (viewClient!=d->curDialogViewGUIClient) {
|
|
//view clients differ
|
|
kdDebug()<<"KexiMainWindowImpl::activeWindowChanged(): old view gui client:"
|
|
<<d->curDialogViewGUIClient<<" new view gui client: "<<viewClient<<endl;
|
|
if (d->curDialogViewGUIClient) {
|
|
guiFactory()->removeClient(d->curDialogViewGUIClient);
|
|
}
|
|
if (viewClient) {
|
|
if (d->closedDialogViewGUIClient) {
|
|
//ooh, there is a client which dialog is already closed -- BUT it is the same client as our
|
|
//so: give up
|
|
}
|
|
else {
|
|
guiFactory()->addClient(viewClient);
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
bool update_dlg_caption = dlg && dlg!=(KexiDialogBase*)d->curDialog && dlg->mdiParent();
|
|
|
|
if (d->curDialogGUIClient && !client)
|
|
guiFactory()->removeClient(d->curDialogGUIClient);
|
|
d->curDialogGUIClient=client;
|
|
|
|
if (d->curDialogViewGUIClient && !viewClient)
|
|
guiFactory()->removeClient(d->curDialogViewGUIClient);
|
|
d->curDialogViewGUIClient=viewClient;
|
|
|
|
bool dialogChanged = ((KexiDialogBase*)d->curDialog)!=dlg;
|
|
|
|
if (dialogChanged) {
|
|
if (d->curDialog) {
|
|
//inform previously activated dialog about deactivation
|
|
d->curDialog->deactivate();
|
|
}
|
|
}
|
|
d->curDialog=dlg;
|
|
|
|
//moved below: propertySetSwitched(d->curDialog);
|
|
|
|
updateCustomPropertyPanelTabs(prevDialog, prevDialog ? prevDialog->currentViewMode() : Kexi::NoViewMode);
|
|
|
|
// inform the current view of the new dialog about property switching
|
|
// (this will also call KexiMainWindowImpl::propertySetSwitched() to update the current property editor's set
|
|
if (dialogChanged && d->curDialog)
|
|
d->curDialog->selectedView()->propertySetSwitched();
|
|
|
|
if (dialogChanged) {
|
|
// invalidateSharedActions();
|
|
//update property editor's contents...
|
|
// if ((KexiPropertyBuffer*)d->propBuffer!=d->curDialog->propertyBuffer()) {
|
|
// propertyBufferSwitched();//d->curDialog);
|
|
// d->propBuffer = d->curDialog->propertyBuffer();
|
|
// d->propEditor->editor()->setBuffer( d->propBuffer );
|
|
// }
|
|
if (d->curDialog && d->curDialog->currentViewMode()!=0) //on opening new dialog it can be 0; we don't want this
|
|
d->updatePropEditorVisibility(d->curDialog->currentViewMode());
|
|
}
|
|
|
|
//update caption...
|
|
if (update_dlg_caption) {//d->curDialog is != null for sure
|
|
slotCaptionForCurrentMDIChild(d->curDialog->mdiParent()->state()==KMdiChildFrm::Maximized);
|
|
}
|
|
// if (!d->curDialog.isNull())
|
|
// d->last_checked_mode = d->actions_for_view_modes[ d->curDialog->currentViewMode() ];
|
|
invalidateViewModeActions();
|
|
invalidateActions();
|
|
d->updateFindDialogContents();
|
|
if (dlg)
|
|
dlg->setFocus();
|
|
}
|
|
|
|
bool
|
|
KexiMainWindowImpl::activateWindow(int id)
|
|
{
|
|
kdDebug() << "KexiMainWindowImpl::activateWindow()" << endl;
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
return activateWindow( d->openedDialogFor( id, pendingType ) );
|
|
#else
|
|
return activateWindow( d->openedDialogFor( id ) );
|
|
#endif
|
|
}
|
|
|
|
bool
|
|
KexiMainWindowImpl::activateWindow(KexiDialogBase *dlg)
|
|
{
|
|
kdDebug() << "KexiMainWindowImpl::activateWindow(KexiDialogBase *)" << endl;
|
|
if(!dlg)
|
|
return false;
|
|
|
|
d->focus_before_popup = dlg;
|
|
dlg->activate();
|
|
return true;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::childClosed(KMdiChildView *v)
|
|
{
|
|
KexiDialogBase *dlg = static_cast<KexiDialogBase *>(v);
|
|
d->removeDialog(dlg->id());
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog(dlg->id());
|
|
#endif
|
|
|
|
//focus navigator if nothing else available
|
|
if (d->openedDialogsCount() == 0)
|
|
d->nav->setFocus();
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotShowSettings()
|
|
{
|
|
KEXI_UNFINISHED(d->action_configure->text());
|
|
//TODO KexiSettings s(this);
|
|
// s.exec();
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotConfigureKeys()
|
|
{
|
|
/* KKeyDialog dlg;
|
|
dlg.insert( actionCollection() );
|
|
dlg.configure();*/
|
|
KKeyDialog::configure( actionCollection(), false/*bAllowLetterShortcuts*/, this );
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotConfigureToolbars()
|
|
{
|
|
KEditToolbar edit(factory());
|
|
// connect(&edit,TQT_SIGNAL(newToolbarConfig()),this,TQT_SLOT(slotNewToolbarConfig()));
|
|
(void) edit.exec();
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectNew()
|
|
{
|
|
if (!d->prj) {
|
|
//create within this instance
|
|
createBlankProject();
|
|
return;
|
|
}
|
|
//TODO use KexiStartupDialog(KexiStartupDialog::Templates...)
|
|
|
|
bool cancel;
|
|
TQString fileName;
|
|
KexiProjectData *new_data = createBlankProjectData(
|
|
cancel,
|
|
false, /* do not confirm prj overwrites: user will be asked on process startup */
|
|
&fileName //shortcut fname
|
|
);
|
|
if (!new_data)
|
|
return;
|
|
|
|
TQStringList args;
|
|
args << tqApp->applicationFilePath() << "-create-opendb";
|
|
if (new_data->connectionData()->fileName().isEmpty()) {
|
|
//server based - pass .kexic file
|
|
if (fileName.isEmpty())
|
|
return;
|
|
args << new_data->databaseName() << fileName;
|
|
//args << "--skip-conn-dialog"; //user does not expect conn. dialog to be shown here
|
|
}
|
|
else {
|
|
//file based
|
|
fileName = new_data->connectionData()->fileName();
|
|
args << fileName;
|
|
}
|
|
//todo: pass new_data->caption()
|
|
//start new instance
|
|
//! @todo use TDEProcess?
|
|
TQProcess proc(args, TQT_TQOBJECT(this), "process");
|
|
proc.setCommunication((TQProcess::Communication)0);
|
|
// proc.setWorkingDirectory( TQFileInfo(new_data->connectionData()->fileName()).dir(true) );
|
|
proc.setWorkingDirectory( TQFileInfo(fileName).dir(true) );
|
|
if (!proc.start()) {
|
|
d->showStartProcessMsg(args);
|
|
}
|
|
delete new_data;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::createKexiProject(KexiProjectData* new_data)
|
|
{
|
|
d->prj = new KexiProject( new_data, this );
|
|
// d->prj = ::createKexiProject(new_data);
|
|
//provided by KexiMessageHandler connect(d->prj, TQT_SIGNAL(error(const TQString&,KexiDB::Object*)), TQT_TQOBJECT(this), TQT_SLOT(showErrorMessage(const TQString&,KexiDB::Object*)));
|
|
//provided by KexiMessageHandler connect(d->prj, TQT_SIGNAL(error(const TQString&,const TQString&)), TQT_TQOBJECT(this), TQT_SLOT(showErrorMessage(const TQString&,const TQString&)));
|
|
connect(d->prj, TQT_SIGNAL(itemRenamed(const KexiPart::Item&, const TQCString&)), TQT_TQOBJECT(this), TQT_SLOT(slotObjectRenamed(const KexiPart::Item&, const TQCString&)));
|
|
|
|
if (d->nav)
|
|
connect(d->prj, TQT_SIGNAL(itemRemoved(const KexiPart::Item&)), d->nav, TQT_SLOT(slotRemoveItem(const KexiPart::Item&)));
|
|
}
|
|
|
|
KexiProjectData*
|
|
KexiMainWindowImpl::createBlankProjectData(bool &cancelled, bool confirmOverwrites,
|
|
TQString* shortcutFileName)
|
|
{
|
|
cancelled = false;
|
|
KexiNewProjectWizard wiz(Kexi::connset(), 0, "KexiNewProjectWizard", true);
|
|
wiz.setConfirmOverwrites(confirmOverwrites);
|
|
if (wiz.exec() != TQDialog::Accepted) {
|
|
cancelled=true;
|
|
return 0;
|
|
}
|
|
|
|
KexiProjectData *new_data;
|
|
|
|
if (shortcutFileName)
|
|
*shortcutFileName = TQString();
|
|
if (wiz.projectConnectionData()) {
|
|
//server-based project
|
|
KexiDB::ConnectionData *cdata = wiz.projectConnectionData();
|
|
kdDebug() << "DBNAME: " << wiz.projectDBName() << " SERVER: " << cdata->serverInfoString() << endl;
|
|
new_data = new KexiProjectData( *cdata, wiz.projectDBName(), wiz.projectCaption() );
|
|
if (shortcutFileName)
|
|
*shortcutFileName = Kexi::connset().fileNameForConnectionData(cdata);
|
|
}
|
|
else if (!wiz.projectDBName().isEmpty()) {
|
|
//file-based project
|
|
KexiDB::ConnectionData cdata;
|
|
cdata.caption = wiz.projectCaption();
|
|
cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName();
|
|
cdata.setFileName( wiz.projectDBName() );
|
|
new_data = new KexiProjectData( cdata, wiz.projectDBName(), wiz.projectCaption() );
|
|
}
|
|
else {
|
|
cancelled = true;
|
|
return 0;
|
|
}
|
|
return new_data;
|
|
}
|
|
|
|
tristate
|
|
KexiMainWindowImpl::createBlankProject()
|
|
{
|
|
bool cancel;
|
|
KexiProjectData *new_data = createBlankProjectData(cancel);
|
|
if (cancel)
|
|
return cancelled;
|
|
if (!new_data)
|
|
return false;
|
|
|
|
createKexiProject( new_data );
|
|
|
|
tristate res = d->prj->create(true /*overwrite*/ );
|
|
if (res != true) {
|
|
delete d->prj;
|
|
d->prj = 0;
|
|
return res;
|
|
}
|
|
kdDebug() << "KexiMainWindowImpl::slotProjectNew(): new project created --- " << endl;
|
|
initNavigator();
|
|
Kexi::recentProjects().addProjectData( new_data );
|
|
|
|
invalidateActions();
|
|
updateAppCaption();
|
|
return true;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectOpen()
|
|
{
|
|
KexiStartupDialog dlg(
|
|
KexiStartupDialog::OpenExisting, 0, Kexi::connset(), Kexi::recentProjects(),
|
|
this, "KexiOpenDialog");
|
|
|
|
if (dlg.exec()!=TQDialog::Accepted)
|
|
return;
|
|
|
|
openProject(dlg.selectedFileName(), dlg.selectedExistingConnection());
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::openProject(const TQString& aFileName,
|
|
const TQString& fileNameForConnectionData, const TQString& dbName)
|
|
{
|
|
if (d->prj)
|
|
return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName);
|
|
|
|
KexiDB::ConnectionData *cdata = 0;
|
|
if (!fileNameForConnectionData.isEmpty()) {
|
|
cdata = Kexi::connset().connectionDataForFileName( fileNameForConnectionData );
|
|
if (!cdata) {
|
|
kdWarning() << "KexiMainWindowImpl::openProject() cdata?" << endl;
|
|
return false;
|
|
}
|
|
}
|
|
return openProject(aFileName, cdata, dbName);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::openProject(const TQString& aFileName,
|
|
KexiDB::ConnectionData *cdata, const TQString& dbName,
|
|
const TQValueList<KexiProjectData::ObjectInfo>& autoopenObjects)
|
|
{
|
|
if (d->prj) {
|
|
return openProjectInExternalKexiInstance(aFileName, cdata, dbName);
|
|
}
|
|
|
|
KexiProjectData* projectData = 0;
|
|
bool deleteAfterOpen = false;
|
|
if (cdata) {
|
|
//server-based project
|
|
if (dbName.isEmpty()) {//no database name given, ask user
|
|
bool cancel;
|
|
projectData = Kexi::startupHandler().selectProject( cdata, cancel, this );
|
|
if (cancel)
|
|
return cancelled;
|
|
}
|
|
else {
|
|
//! @todo caption arg?
|
|
projectData = new KexiProjectData( *cdata, dbName );
|
|
deleteAfterOpen = true;
|
|
}
|
|
}
|
|
else {
|
|
// TQString selFile = dlg.selectedExistingFile();
|
|
if (aFileName.isEmpty()) {
|
|
kdWarning() << "KexiMainWindowImpl::openProject(): aFileName.isEmpty()" << endl;
|
|
return false;
|
|
}
|
|
//file-based project
|
|
kdDebug() << "Project File: " << aFileName << endl;
|
|
KexiDB::ConnectionData cdata;
|
|
cdata.setFileName( aFileName );
|
|
// cdata.driverName = KexiStartupHandler::detectDriverForFile( cdata.driverName, fileName, this );
|
|
TQString detectedDriverName;
|
|
KexiStartupData::Import importActionData;
|
|
const tristate res = KexiStartupHandler::detectActionForFile(
|
|
importActionData, detectedDriverName, cdata.driverName, aFileName, this );
|
|
if (true != res)
|
|
return res;
|
|
|
|
if (importActionData) { //importing requested
|
|
return showProjectMigrationWizard( importActionData.mimeType, importActionData.fileName );
|
|
}
|
|
cdata.driverName = detectedDriverName;
|
|
|
|
if (cdata.driverName.isEmpty())
|
|
return false;
|
|
|
|
//opening requested
|
|
projectData = new KexiProjectData(cdata, aFileName);
|
|
deleteAfterOpen = true;
|
|
}
|
|
if (!projectData)
|
|
return false;
|
|
projectData->autoopenObjects = autoopenObjects;
|
|
const tristate res = openProject(*projectData);
|
|
if (deleteAfterOpen) //projectData object has been copied
|
|
delete projectData;
|
|
return res;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::openProjectInExternalKexiInstance(const TQString& aFileName,
|
|
KexiDB::ConnectionData *cdata, const TQString& dbName)
|
|
{
|
|
TQString fileNameForConnectionData;
|
|
if (aFileName.isEmpty()) { //try .kexic file
|
|
if (cdata)
|
|
fileNameForConnectionData = Kexi::connset().fileNameForConnectionData(cdata);
|
|
}
|
|
return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::openProjectInExternalKexiInstance(const TQString& aFileName,
|
|
const TQString& fileNameForConnectionData, const TQString& dbName)
|
|
{
|
|
TQString fileName(aFileName);
|
|
TQStringList args;
|
|
args << tqApp->applicationFilePath();
|
|
// open a file-based project or a server connection provided as a .kexic file
|
|
// (we have no other simple way to provide the startup data to a new process)
|
|
if (fileName.isEmpty()) { //try .kexic file
|
|
if (!fileNameForConnectionData.isEmpty())
|
|
args << "--skip-conn-dialog"; //user does not expect conn. dialog to be shown here
|
|
|
|
if (dbName.isEmpty()) { //use 'kexi --skip-conn-dialog file.kexic'
|
|
fileName = fileNameForConnectionData;
|
|
}
|
|
else { //use 'kexi --skip-conn-dialog --connection file.kexic dbName'
|
|
args << "--connection" << fileNameForConnectionData;
|
|
fileName = dbName;
|
|
}
|
|
}
|
|
if (fileName.isEmpty()) {
|
|
kdWarning() << "KexiMainWindowImpl::openProjectInExternalKexiInstance() fileName?" << endl;
|
|
return false;
|
|
}
|
|
//! @todo use KRun
|
|
args << fileName;
|
|
TQProcess proc(args, TQT_TQOBJECT(this), "process");
|
|
proc.setWorkingDirectory( TQFileInfo(fileName).dir(true) );
|
|
const bool ok = proc.start();
|
|
if (!ok) {
|
|
d->showStartProcessMsg(args);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectOpenRecentAboutToShow()
|
|
{
|
|
/*
|
|
//setup
|
|
TDEPopupMenu *popup = d->action_open_recent->popupMenu();
|
|
const int cnt = popup->count();
|
|
//remove older
|
|
for (int i = 0; i<cnt; i++) {
|
|
int id = popup->idAt(0);
|
|
if (id==d->action_open_recent_more_id)
|
|
break;
|
|
if (id>=0) {
|
|
popup->removeItem(id);
|
|
}
|
|
}
|
|
//insert current items
|
|
int cur_id = 0, cur_idx = 0;
|
|
//TODO:
|
|
cur_id = popup->insertItem("My example project 1", ++cur_id, cur_idx++);
|
|
cur_id = popup->insertItem("My example project 2", ++cur_id, cur_idx++);
|
|
cur_id = popup->insertItem("My example project 3", ++cur_id, cur_idx++);
|
|
*/
|
|
|
|
//show recent databases
|
|
TDEPopupMenu *popup = d->action_open_recent->popupMenu();
|
|
popup->clear();
|
|
#if 0
|
|
d->action_open_recent_projects_title_id = popup->insertTitle(i18n("Recently Opened Databases"));
|
|
#endif
|
|
// int action_open_recent_projects_title_index = popup->indexOf(d->action_open_recent_projects_title_id);
|
|
// int count = popup->count();
|
|
// int action_open_recent_connections_title_index = popup->indexOf(d->action_open_recent_connections_title_id);
|
|
// for (int i=action_open_recent_projects_title_index+1;
|
|
// i<action_open_recent_connections_title_index; i++)
|
|
// {
|
|
// popup->removeItemAt(action_open_recent_projects_title_index+1);
|
|
// }
|
|
|
|
// int cur_idx = action_open_recent_projects_title_index+1;
|
|
popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 1");
|
|
popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 2");
|
|
popup->insertItem(SmallIconSet("kexiproject_sqlite"), "My project 3");
|
|
|
|
#if 0
|
|
//show recent connections
|
|
d->action_open_recent_connections_title_id =
|
|
d->action_open_recent->popupMenu()->insertTitle(i18n("Recently Connected Database Servers"));
|
|
|
|
// cur_idx = popup->indexOf(d->action_open_recent_connections_title_id) + 1;
|
|
// for (int i=cur_idx; i<count; i++) {
|
|
// popup->removeItemAt(cur_idx);
|
|
// }
|
|
popup->insertItem(SmallIconSet("socket"), "My connection 1");
|
|
popup->insertItem(SmallIconSet("socket"), "My connection 2");
|
|
popup->insertItem(SmallIconSet("socket"), "My connection 3");
|
|
popup->insertItem(SmallIconSet("socket"), "My connection 4");
|
|
#endif
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectOpenRecent(int id)
|
|
{
|
|
if (id<0) // || id==d->action_open_recent_more_id)
|
|
return;
|
|
kdDebug() << "KexiMainWindowImpl::slotProjectOpenRecent("<<id<<")"<<endl;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectOpenRecentMore()
|
|
{
|
|
KEXI_UNFINISHED(i18n("Open Recent"));
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectSave()
|
|
{
|
|
if (!d->curDialog)
|
|
return;
|
|
saveObject( d->curDialog );
|
|
updateAppCaption();
|
|
invalidateActions();
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectSaveAs()
|
|
{
|
|
KEXI_UNFINISHED(i18n("Save object as"));
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectPrint()
|
|
{
|
|
if (d->curDialog && d->curDialog->partItem())
|
|
printItem(d->curDialog->partItem());
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectPrintPreview()
|
|
{
|
|
if (d->curDialog && d->curDialog->partItem())
|
|
printPreviewForItem(d->curDialog->partItem());
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectPageSetup()
|
|
{
|
|
if (d->curDialog && d->curDialog->partItem())
|
|
showPageSetupForItem(d->curDialog->partItem());
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotProjectExportDataTable()
|
|
{
|
|
if (d->curDialog && d->curDialog->partItem())
|
|
exportItemAsDataTable(d->curDialog->partItem());
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectProperties()
|
|
{
|
|
//TODO: load the implementation not the ui :)
|
|
// ProjectSettingsUI u(this);
|
|
// u.exec();
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectClose()
|
|
{
|
|
closeProject();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotProjectRelations()
|
|
{
|
|
if (!d->prj)
|
|
return;
|
|
KexiDialogBase *d = KexiInternalPart::createKexiDialogInstance("relation", this, this);
|
|
activateWindow(d);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotImportFile()
|
|
{
|
|
KEXI_UNFINISHED("Import: " + i18n("From File..."));
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotImportServer()
|
|
{
|
|
KEXI_UNFINISHED("Import: " + i18n("From Server..."));
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::slotProjectQuit()
|
|
{
|
|
if (~ closeProject())
|
|
return;
|
|
close();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotViewNavigator()
|
|
{
|
|
if (!d->nav || !d->navToolWindow)
|
|
return;
|
|
if (!d->nav->isVisible())
|
|
makeWidgetDockVisible(d->nav);
|
|
// makeDockVisible(dynamic_cast<KDockWidget*>(d->navToolWindow->wrapperWidget()));
|
|
// d->navToolWindow->wrapperWidget()->show();
|
|
// d->navToolWindow->show(KDockWidget::DockLeft, getMainDockWidget());
|
|
|
|
d->navToolWindow->wrapperWidget()->raise();
|
|
//
|
|
d->block_KMdiMainFrm_eventFilter=true;
|
|
d->nav->setFocus();
|
|
d->block_KMdiMainFrm_eventFilter=false;
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotViewMainArea()
|
|
{
|
|
if (d->curDialog)
|
|
d->curDialog->setFocus();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotViewPropertyEditor()
|
|
{
|
|
if (!d->propEditor || !d->propEditorToolWindow)
|
|
return;
|
|
|
|
//js d->config->setGroup("MainWindow");
|
|
//js ds->setSeparatorPos(d->config->readNumEntry("RightDockPosition", 80/* % */), true);
|
|
|
|
if (!d->propEditorTabWidget->isVisible())
|
|
makeWidgetDockVisible(d->propEditorTabWidget);
|
|
|
|
|
|
d->propEditorToolWindow->wrapperWidget()->raise();
|
|
|
|
d->block_KMdiMainFrm_eventFilter=true;
|
|
if (d->propEditorTabWidget->currentPage())
|
|
d->propEditorTabWidget->currentPage()->setFocus();
|
|
d->block_KMdiMainFrm_eventFilter=false;
|
|
|
|
/*#if defined(KDOCKWIDGET_P)
|
|
KDockWidget *dw = (KDockWidget *)d->propEditor->parentWidget();
|
|
KDockSplitter *ds = (KDockSplitter *)dw->parentWidget();
|
|
ds->setSeparatorPos(80,true);//d->config->readNumEntry("RightDockPosition", 80), true);
|
|
#endif*/
|
|
}
|
|
|
|
bool KexiMainWindowImpl::switchToViewMode(int viewMode)
|
|
{
|
|
if (!d->curDialog) {
|
|
d->toggleLastCheckedMode();
|
|
return false;
|
|
}
|
|
if (!d->curDialog->supportsViewMode( viewMode )) {
|
|
showErrorMessage(i18n("Selected view is not supported for \"%1\" object.")
|
|
.arg(d->curDialog->partItem()->name()),
|
|
i18n("Selected view (%1) is not supported by this object type (%2).")
|
|
.arg(Kexi::nameForViewMode(viewMode))
|
|
.arg(d->curDialog->part()->instanceCaption()) );
|
|
d->toggleLastCheckedMode();
|
|
return false;
|
|
}
|
|
int prevViewMode = d->curDialog->currentViewMode();
|
|
updateCustomPropertyPanelTabs(d->curDialog->part(), prevViewMode,
|
|
d->curDialog->part(), viewMode );
|
|
tristate res = d->curDialog->switchToViewMode( viewMode );
|
|
if (!res) {
|
|
updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
|
|
showErrorMessage(i18n("Switching to other view failed (%1).").arg(Kexi::nameForViewMode(viewMode)),
|
|
d->curDialog);
|
|
d->toggleLastCheckedMode();
|
|
return false;
|
|
}
|
|
if (~res) {
|
|
updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
|
|
d->toggleLastCheckedMode();
|
|
return false;
|
|
}
|
|
|
|
//view changed: switch to this view's gui client
|
|
KXMLGUIClient *viewClient=d->curDialog->guiClient();
|
|
updateDialogViewGUIClient(viewClient);
|
|
if (d->curDialogViewGUIClient && !viewClient)
|
|
guiFactory()->removeClient(d->curDialogViewGUIClient);
|
|
d->curDialogViewGUIClient=viewClient; //remember
|
|
|
|
d->updatePropEditorVisibility(viewMode);
|
|
invalidateProjectWideActions();
|
|
invalidateSharedActions();
|
|
d->updateFindDialogContents();
|
|
return true;
|
|
}
|
|
|
|
|
|
void KexiMainWindowImpl::slotViewDataMode()
|
|
{
|
|
switchToViewMode(Kexi::DataViewMode);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotViewDesignMode()
|
|
{
|
|
switchToViewMode(Kexi::DesignViewMode);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotViewTextMode()
|
|
{
|
|
switchToViewMode(Kexi::TextViewMode);
|
|
}
|
|
|
|
void KexiMainWindowImpl::closeWindow(KMdiChildView *pWnd, bool layoutTaskBar)
|
|
{
|
|
if (d->insideCloseDialog && dynamic_cast<KexiDialogBase *>(pWnd)) {
|
|
d->windowsToClose.append(dynamic_cast<KexiDialogBase *>(pWnd));
|
|
return;
|
|
}
|
|
/*moved to closeDialog()
|
|
if (pWnd == d->curDialog && !pWnd->isAttached()) {
|
|
if (d->propEditor) {
|
|
// ah, closing detached window - better switch off property buffer right now...
|
|
d->propBuffer = 0;
|
|
d->propEditor->editor()->setBuffer( 0, false );
|
|
}
|
|
}
|
|
*/
|
|
closeDialog(dynamic_cast<KexiDialogBase *>(pWnd), layoutTaskBar);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::getNewObjectInfo(
|
|
KexiPart::Item *partItem, KexiPart::Part *part,
|
|
bool& allowOverwriting, const TQString& messageWhenAskingForName )
|
|
{
|
|
//data was never saved in the past -we need to create a new object at the backend
|
|
KexiPart::Info *info = part->info();
|
|
#ifdef KEXI_ADD_CUSTOM_OBJECT_CREATION
|
|
# include "keximainwindowimpl_customobjcreation.h"
|
|
#endif
|
|
if (!d->nameDialog) {
|
|
d->nameDialog = new KexiNameDialog(
|
|
messageWhenAskingForName, this, "nameDialog");
|
|
//check if that name is allowed
|
|
d->nameDialog->widget()->addNameSubvalidator(
|
|
new KexiDB::ObjectNameValidator(project()->dbConnection()->driver(), 0, "sub"));
|
|
}
|
|
else {
|
|
d->nameDialog->widget()->setMessageText( messageWhenAskingForName );
|
|
}
|
|
d->nameDialog->widget()->setCaptionText(partItem->caption());
|
|
d->nameDialog->widget()->setNameText(partItem->name());
|
|
d->nameDialog->setCaption(i18n("Save Object As"));
|
|
d->nameDialog->setDialogIcon( DesktopIcon( info->itemIcon(), TDEIcon::SizeMedium ) );
|
|
allowOverwriting = false;
|
|
bool found;
|
|
do {
|
|
if (d->nameDialog->exec()!=TQDialog::Accepted)
|
|
return cancelled;
|
|
//check if that name already exists
|
|
KexiDB::SchemaData tmp_sdata;
|
|
tristate result = project()->dbConnection()->loadObjectSchemaData(
|
|
info->projectPartID(),
|
|
d->nameDialog->widget()->nameText(), tmp_sdata );
|
|
if (!result)
|
|
return false;
|
|
found = result==true;
|
|
if (found) {
|
|
if (allowOverwriting) {
|
|
int res = KMessageBox::warningYesNoCancel(this,
|
|
"<p>"+part->i18nMessage("Object \"%1\" already exists.", 0)
|
|
.arg(d->nameDialog->widget()->nameText())
|
|
+"</p><p>"+i18n("Do you want to replace it?")+"</p>", 0,
|
|
KGuiItem(i18n("&Replace"), "button_yes"),
|
|
KGuiItem(i18n("&Choose Other Name...")),
|
|
TQString(), KMessageBox::Notify|KMessageBox::Dangerous);
|
|
if (res == KMessageBox::No)
|
|
continue;
|
|
else if (res == KMessageBox::Cancel)
|
|
return cancelled;
|
|
else {//yes
|
|
allowOverwriting = true;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
KMessageBox::information(this,
|
|
"<p>"+part->i18nMessage("Object \"%1\" already exists.", 0)
|
|
.arg(d->nameDialog->widget()->nameText())
|
|
+"</p><p>"+i18n("Please choose other name.")+"</p>");
|
|
// " For example: Table \"my_table\" already exists" ,
|
|
// "%1 \"%2\" already exists.\nPlease choose other name.")
|
|
// .arg(dlg->part()->instanceName()).arg(d->nameDialog->widget()->nameText()));
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
while (found);
|
|
|
|
//update name and caption
|
|
partItem->setName( d->nameDialog->widget()->nameText() );
|
|
partItem->setCaption( d->nameDialog->widget()->captionText() );
|
|
return true;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::saveObject( KexiDialogBase *dlg, const TQString& messageWhenAskingForName,
|
|
bool dontAsk)
|
|
{
|
|
tristate res;
|
|
if (!dlg->neverSaved()) {
|
|
//data was saved in the past -just save again
|
|
res = dlg->storeData(dontAsk);
|
|
if (!res)
|
|
showErrorMessage(i18n("Saving \"%1\" object failed.").arg(dlg->partItem()->name()),
|
|
d->curDialog);
|
|
return res;
|
|
}
|
|
|
|
const int oldItemID = dlg->partItem()->identifier();
|
|
|
|
bool allowOverwriting = false;
|
|
res = getNewObjectInfo( dlg->partItem(), dlg->part(), allowOverwriting,
|
|
messageWhenAskingForName );
|
|
if (res != true)
|
|
return res;
|
|
|
|
res = dlg->storeNewData();
|
|
if (~res)
|
|
return cancelled;
|
|
if (!res) {
|
|
showErrorMessage(i18n("Saving new \"%1\" object failed.").arg(dlg->partItem()->name()),
|
|
d->curDialog);
|
|
return false;
|
|
}
|
|
|
|
//update navigator
|
|
//this is alreday done in KexiProject::addStoredItem(): d->nav->addItem(dlg->partItem());
|
|
//item id changed to final one: update association in dialogs' dictionary
|
|
// d->dialogs.take(oldItemID);
|
|
d->updateDialogId(dlg, oldItemID);
|
|
invalidateProjectWideActions();
|
|
return true;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::closeDialog(KexiDialogBase *dlg)
|
|
{
|
|
return closeDialog(dlg, true);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::closeDialog(KexiDialogBase *dlg, bool layoutTaskBar, bool doNotSaveChanges)
|
|
{
|
|
if (!dlg)
|
|
return true;
|
|
if (d->insideCloseDialog)
|
|
return true;
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->addItemToPendingDialogs(dlg->partItem(), Private::DialogClosingJob);
|
|
#endif
|
|
|
|
d->insideCloseDialog = true;
|
|
|
|
if (dlg == d->curDialog && !dlg->isAttached()) {
|
|
if (d->propEditor) {
|
|
// ah, closing detached window - better switch off property buffer right now...
|
|
d->propBuffer = 0;
|
|
d->propEditor->editor()->changeSet( 0, false );
|
|
}
|
|
}
|
|
|
|
bool remove_on_closing = dlg->partItem() ? dlg->partItem()->neverSaved() : false;
|
|
if (dlg->dirty() && !d->forceDialogClosing && !doNotSaveChanges) {
|
|
//more accurate tool tips and what's this
|
|
KGuiItem saveChanges( KStdGuiItem::save() );
|
|
saveChanges.setToolTip(i18n("Save changes"));
|
|
saveChanges.setWhatsThis(
|
|
i18n( "Pressing this button will save all recent changes made in \"%1\" object." )
|
|
.arg(dlg->partItem()->name()) );
|
|
KGuiItem discardChanges( KStdGuiItem::discard() );
|
|
discardChanges.setWhatsThis(
|
|
i18n( "Pressing this button will discard all recent changes made in \"%1\" object." )
|
|
.arg(dlg->partItem()->name()) );
|
|
|
|
//dialog's data is dirty:
|
|
//--adidional message, e.g. table designer will return
|
|
// "Note: This table is already filled with data which will be removed."
|
|
// if the dlg is in design view mode.
|
|
TQString additionalMessage = dlg->part()->i18nMessage(
|
|
":additional message before saving design", dlg);
|
|
if (additionalMessage.startsWith(":"))
|
|
additionalMessage = TQString();
|
|
if (!additionalMessage.isEmpty())
|
|
additionalMessage = "<p>"+additionalMessage+"</p>";
|
|
|
|
const int questionRes = KMessageBox::warningYesNoCancel( this,
|
|
"<p>"+dlg->part()->i18nMessage("Design of object \"%1\" has been modified.", dlg)
|
|
.arg(dlg->partItem()->name())+"</p><p>"+i18n("Do you want to save changes?")+"</p>"
|
|
+ additionalMessage /*may be empty*/,
|
|
TQString(),
|
|
saveChanges,
|
|
discardChanges);
|
|
if (questionRes==KMessageBox::Cancel) {
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog(dlg->id());
|
|
#endif
|
|
d->insideCloseDialog = false;
|
|
d->windowsToClose.clear(); //give up with 'close all'
|
|
return cancelled;
|
|
}
|
|
if (questionRes==KMessageBox::Yes) {
|
|
//save it
|
|
// if (!dlg->storeData())
|
|
tristate res = saveObject( dlg, TQString(), true /*dontAsk*/ );
|
|
if (!res || ~res) {
|
|
//js:TODO show error info; (retry/ignore/cancel)
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog(dlg->id());
|
|
#endif
|
|
d->insideCloseDialog = false;
|
|
d->windowsToClose.clear(); //give up with 'close all'
|
|
return res;
|
|
}
|
|
remove_on_closing = false;
|
|
}
|
|
}
|
|
|
|
const int dlg_id = dlg->id(); //remember now, because removeObject() can destruct partitem object
|
|
|
|
if (remove_on_closing) {
|
|
//we won't save this object, and it was never saved -remove it
|
|
if (!removeObject( dlg->partItem(), true )) {
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog(dlg->id());
|
|
#endif
|
|
//msg?
|
|
//TODO: ask if we'd continue and return true/false
|
|
d->insideCloseDialog = false;
|
|
d->windowsToClose.clear(); //give up with 'close all'
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
//not dirty now
|
|
if(d->nav)
|
|
d->nav->updateItemName( *dlg->partItem(), false );
|
|
}
|
|
|
|
d->removeDialog(dlg_id); //don't remove -KMDI will do that
|
|
//also remove from 'print setup dialogs' cache, if needed
|
|
int printedObjectID = 0;
|
|
if (d->pageSetupDialogItemID2dataItemID_map.contains(dlg_id))
|
|
printedObjectID = d->pageSetupDialogItemID2dataItemID_map[ dlg_id ];
|
|
d->pageSetupDialogs.take(printedObjectID);
|
|
|
|
KXMLGUIClient *client = dlg->commonGUIClient();
|
|
KXMLGUIClient *viewClient = dlg->guiClient();
|
|
if (d->curDialogGUIClient==client) {
|
|
d->curDialogGUIClient=0;
|
|
}
|
|
if (d->curDialogViewGUIClient==viewClient) {
|
|
d->curDialogViewGUIClient=0;
|
|
}
|
|
if (client) {
|
|
//sanity: ouch, it is not removed yet? - do it now
|
|
if (d->closedDialogGUIClient && d->closedDialogGUIClient!=client)
|
|
guiFactory()->removeClient(d->closedDialogGUIClient);
|
|
if (d->openedDialogsCount()==0) {//now there is no dialogs - remove client RIGHT NOW!
|
|
d->closedDialogGUIClient=0;
|
|
guiFactory()->removeClient(client);
|
|
}
|
|
else {
|
|
//remember this - and MAYBE remove later, if needed
|
|
d->closedDialogGUIClient=client;
|
|
}
|
|
}
|
|
if (viewClient) {
|
|
//sanity: ouch, it is not removed yet? - do it now
|
|
if (d->closedDialogViewGUIClient && d->closedDialogViewGUIClient!=viewClient)
|
|
guiFactory()->removeClient(d->closedDialogViewGUIClient);
|
|
if (d->openedDialogsCount()==0) {//now there is no dialogs - remove client RIGHT NOW!
|
|
d->closedDialogViewGUIClient=0;
|
|
guiFactory()->removeClient(viewClient);
|
|
}
|
|
else {
|
|
//remember this - and MAYBE remove later, if needed
|
|
d->closedDialogViewGUIClient=viewClient;
|
|
}
|
|
}
|
|
|
|
const bool isInMaximizedChildFrmMode = this->isInMaximizedChildFrmMode();
|
|
|
|
KMdiMainFrm::closeWindow(dlg, layoutTaskBar);
|
|
|
|
//focus navigator if nothing else available
|
|
if (d->openedDialogsCount()==0) {
|
|
d->maximizeFirstOpenedChildFrm = isInMaximizedChildFrmMode;
|
|
if (d->nav)
|
|
d->nav->setFocus();
|
|
d->updatePropEditorVisibility(0);
|
|
}
|
|
|
|
invalidateActions();
|
|
d->insideCloseDialog = false;
|
|
if (!d->windowsToClose.isEmpty()) //continue 'close all'
|
|
closeDialog(d->windowsToClose.take(0), true);
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog( dlg_id );
|
|
|
|
//perform pending global action that was suspended:
|
|
if (!d->pendingDialogsExist()) {
|
|
d->executeActionWhenPendingJobsAreFinished();
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void KexiMainWindowImpl::detachWindow(KMdiChildView *pWnd,bool bShow)
|
|
{
|
|
KMdiMainFrm::detachWindow(pWnd,bShow);
|
|
// update icon - from small to large
|
|
pWnd->setIcon( DesktopIcon( static_cast<KexiDialogBase *>(pWnd)->itemIcon() ) );
|
|
// pWnd->setIcon( DesktopIcon( static_cast<KexiDialogBase *>(pWnd)->part()->info()->itemIcon() ) );
|
|
if (dynamic_cast<KexiDialogBase*>(pWnd))
|
|
dynamic_cast<KexiDialogBase*>(pWnd)->sendDetachedStateToCurrentView();
|
|
}
|
|
|
|
void KexiMainWindowImpl::attachWindow(KMdiChildView *pWnd, bool /*bShow*/, bool bAutomaticResize)
|
|
{
|
|
// if (bAutomaticResize || w->size().isEmpty() || (w->size() == TQSize(1,1))) {
|
|
KMdiMainFrm::attachWindow(pWnd,true,bAutomaticResize);
|
|
//for dialogs in normal state: decrease dialog's height if it exceeds area contents
|
|
if (pWnd->mdiParent()->state() == KMdiChildFrm::Normal
|
|
&& pWnd->geometry().bottom() > pWnd->mdiParent()->mdiAreaContentsRect().bottom())
|
|
{
|
|
TQRect r = pWnd->geometry();
|
|
r.setBottom( pWnd->mdiParent()->mdiAreaContentsRect().bottom() - 5 );
|
|
pWnd->setGeometry( r );
|
|
}
|
|
// update icon - from large to small
|
|
pWnd->mdiParent()->setIcon( SmallIcon( static_cast<KexiDialogBase *>(pWnd)->itemIcon() ) );
|
|
if (dynamic_cast<KexiDialogBase*>(pWnd))
|
|
dynamic_cast<KexiDialogBase*>(pWnd)->sendAttachedStateToCurrentView();
|
|
}
|
|
|
|
TQWidget* KexiMainWindowImpl::findWindow(TQWidget *w)
|
|
{
|
|
while (w && !acceptsSharedActions(TQT_TQOBJECT(w)))
|
|
w = w->parentWidget();
|
|
return w;
|
|
}
|
|
|
|
bool KexiMainWindowImpl::acceptsSharedActions(TQObject *w)
|
|
{
|
|
return w->inherits("KexiDialogBase") || w->inherits("KexiViewBase");
|
|
}
|
|
|
|
bool KexiMainWindowImpl::eventFilter( TQObject *obj, TQEvent * e )
|
|
{
|
|
//KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name()<<endl;
|
|
if (e->type()==TQEvent::KeyPress) {
|
|
KexiVDebug << "KEY EVENT " << TQString::number(TQT_TQKEYEVENT(e)->key(), 16) << endl;
|
|
KexiVDebug << endl;
|
|
}
|
|
if (e->type()==TQEvent::AccelOverride) {
|
|
//KexiVDebug << "AccelOverride EVENT " << TQT_TQKEYEVENT(e)->key() << " " << TQT_TQKEYEVENT(e)->state() == ControlButton << endl;
|
|
|
|
//avoid sending CTRL+Tab key twice for tabbed/ideal mode, epecially for win32
|
|
if (TQT_TQKEYEVENT(e)->key()==TQt::Key_Tab && TQT_TQKEYEVENT(e)->state() == ControlButton) {
|
|
if (d->action_window_next->shortcut().keyCodeQt()==TQt::Key_Tab+TQt::CTRL && d->action_window_next->shortcut().count()==1
|
|
&& (mdiMode()==KMdi::TabPageMode || mdiMode()==KMdi::IDEAlMode))
|
|
{
|
|
TQT_TQKEYEVENT(e)->accept();
|
|
}
|
|
}
|
|
}
|
|
if (e->type()==TQEvent::Close) {
|
|
KexiVDebug << "Close EVENT" << endl;
|
|
}
|
|
if (e->type()==TQEvent::Resize) {
|
|
KexiVDebug << "Resize EVENT" << endl;
|
|
}
|
|
if (e->type()==TQEvent::ShowMaximized) {
|
|
KexiVDebug << "ShowMaximized EVENT" << endl;
|
|
}
|
|
|
|
/* if (obj==d->propEditor) {
|
|
if (e->type()==TQEvent::Resize) {
|
|
d->updatePropEditorDockWidthInfo();
|
|
}
|
|
}*/
|
|
|
|
TQWidget *focus_w = 0;
|
|
if (obj->inherits("TQPopupMenu")) {
|
|
/* Fixes for popup menus behaviour:
|
|
For hiding/showing: focus previously (d->focus_before_popup)
|
|
focused window, if known, otherwise focus currently focused one.
|
|
And: just invalidate actions.
|
|
*/
|
|
if (e->type()==TQEvent::Hide || e->type()==TQEvent::Show) {
|
|
KexiVDebug << e->type() << endl;
|
|
focus_w = focusWindow();
|
|
if (!d->focus_before_popup.isNull()) {
|
|
d->focus_before_popup->setFocus();
|
|
d->focus_before_popup=0;
|
|
invalidateSharedActions();
|
|
} else {
|
|
if (focus_w) {
|
|
focus_w->setFocus();
|
|
invalidateSharedActions();
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*! On mouse click on the findow, make sure it's focused and actions are invalidated */
|
|
if (e->type()==TQEvent::MouseButtonPress) {
|
|
TQWidget *w = findWindow(TQT_TQWIDGET(obj));
|
|
KexiVDebug << "MouseButtonPress EVENT " << (w ? w->name() : 0) << endl;
|
|
if (w) {
|
|
w->setFocus();
|
|
invalidateSharedActions(TQT_TQOBJECT(d->curDialog));
|
|
}
|
|
}
|
|
TQWidget *w = findWindow(TQT_TQWIDGET(obj));
|
|
if (e->type()==TQEvent::FocusIn) {
|
|
focus_w = focusWindow();
|
|
KexiVDebug << "Focus EVENT" << endl;
|
|
KexiVDebug << (focus_w ? focus_w->name() : "" ) << endl;
|
|
KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name() <<endl;
|
|
#ifdef KEXI_STATUSBAR_DEBUG
|
|
TQWidget *focus_widget = focus_w ? focus_w->focusWidget() : 0;
|
|
d->statusBar->setStatus(TQString("FOCUS VIEW: %1 %2, FOCUS WIDGET: %3 %4")
|
|
.arg(focus_w ? focus_w->className() : "").arg(focus_w ? focus_w->name() : "")
|
|
.arg(focus_widget ? focus_widget->className() : "").arg(focus_widget ? focus_widget->name() : "")
|
|
);
|
|
#endif
|
|
}
|
|
else if (e->type()==TQEvent::FocusOut) {
|
|
focus_w = focusWindow();
|
|
KexiVDebug << "Focus OUT EVENT" << endl;
|
|
KexiVDebug << (focus_w ? focus_w->name() : "" ) << endl;
|
|
KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name() <<endl;
|
|
#ifdef KEXI_STATUSBAR_DEBUG
|
|
TQWidget *focus_widget = focus_w ? focus_w->focusWidget() : 0;
|
|
d->statusBar->setStatus(TQString("FOCUS VIEW: %1 %2, FOCUS WIDGET: %3 %4")
|
|
.arg(focus_w ? focus_w->className() : "").arg(focus_w ? focus_w->name() : "")
|
|
.arg(focus_widget ? focus_widget->className() : "").arg(focus_widget ? focus_widget->name() : "")
|
|
);
|
|
#endif
|
|
}
|
|
if (e->type()==TQEvent::WindowActivate) {
|
|
KexiVDebug << "WindowActivate EVENT" << endl;
|
|
KexiVDebug << "eventFilter: " <<e->type() << " " <<obj->name()<<endl;
|
|
}
|
|
#if 0
|
|
if (e->type()==TQEvent::FocusIn) {
|
|
if (focus_w) {
|
|
// if (d->actionProxies[ w ])
|
|
// if (d->actionProxies[ focus_w ]) {
|
|
if (actionProxyFor( focus_w )) {
|
|
// invalidateSharedActions();
|
|
}
|
|
else {
|
|
/* TQObject* o = focusWidget();
|
|
while (o && !o->inherits("KexiDialogBase") && !o->inherits("KexiDockBase"))
|
|
o = o->parent();*/
|
|
//js invalidateSharedActions(focus_w);
|
|
}
|
|
}
|
|
// /*|| e->type()==TQEvent::FocusOut*/) && /*(!obj->inherits("KexiDialogBase")) &&*/ d->actionProxies[ obj ]) {
|
|
// invalidateSharedActions();
|
|
}
|
|
if (e->type()==TQEvent::FocusOut && focus_w && focus_w==d->curDialog && actionProxyFor( obj )) {
|
|
invalidateSharedActions(d->curDialog);
|
|
}
|
|
#endif
|
|
|
|
if (!d->focus_before_popup.isNull() && e->type()==TQEvent::FocusOut && obj->inherits("KMenuBar")) {
|
|
//d->nav->setFocus();
|
|
d->focus_before_popup->setFocus();
|
|
d->focus_before_popup=0;
|
|
invalidateSharedActions(TQT_TQOBJECT(d->curDialog));
|
|
return true;
|
|
}
|
|
|
|
//remember currently focued window invalidate act.
|
|
if (e->type()==TQEvent::FocusOut) {
|
|
if (TQT_TQFOCUSEVENT(e)->reason()==TQFocusEvent::Popup) {
|
|
if (KexiUtils::hasParent(TQT_TQOBJECT(d->curDialog), TQT_TQOBJECT(focus_w))) {
|
|
invalidateSharedActions(TQT_TQOBJECT(d->curDialog));
|
|
d->focus_before_popup=d->curDialog;
|
|
}
|
|
else {
|
|
//not needed??? invalidateSharedActions(focus_w);
|
|
d->focus_before_popup=focus_w;
|
|
}
|
|
}
|
|
}
|
|
|
|
//keep focus in main window:
|
|
if (w && w==d->nav) {
|
|
// kdDebug() << "NAV" << endl;
|
|
if (e->type()==TQEvent::FocusIn) {
|
|
return true;
|
|
} else if (e->type()==TQEvent::WindowActivate && w==d->focus_before_popup) {
|
|
// d->nav->setFocus();
|
|
d->focus_before_popup=0;
|
|
return true;
|
|
} else if (e->type()==TQEvent::FocusOut) {
|
|
if (TQT_TQFOCUSEVENT(e)->reason()==TQFocusEvent::Tab) {
|
|
//activate current child:
|
|
if (d->curDialog) {
|
|
d->curDialog->activate();
|
|
return true;
|
|
}
|
|
}
|
|
else if (TQT_TQFOCUSEVENT(e)->reason()==TQFocusEvent::Popup) {
|
|
d->focus_before_popup=w;
|
|
}
|
|
//invalidateSharedActions();
|
|
} else if (e->type()==TQEvent::Hide) {
|
|
setFocus();
|
|
return false;
|
|
}
|
|
}
|
|
if (d->block_KMdiMainFrm_eventFilter)//we don't want KMDI to eat our event!
|
|
return false;
|
|
return KMdiMainFrm::eventFilter(obj,e);//let KMDI do its work
|
|
}
|
|
|
|
bool KexiMainWindowImpl::openingAllowed(KexiPart::Item* item, int viewMode)
|
|
{
|
|
//! @todo this can be more complex once we deliver ACLs...
|
|
if (!userMode())
|
|
return true;
|
|
KexiPart::Part * part = Kexi::partManager().partForMimeType(item->mimeType());
|
|
return part && (part->supportedUserViewModes() & viewMode);
|
|
}
|
|
|
|
KexiDialogBase *
|
|
KexiMainWindowImpl::openObject(const TQCString& mimeType, const TQString& name,
|
|
int viewMode, bool &openingCancelled, TQMap<TQString,TQString>* staticObjectArgs)
|
|
{
|
|
KexiPart::Item *item = d->prj->itemForMimeType(mimeType,name);
|
|
if (!item)
|
|
return 0;
|
|
return openObject(item, viewMode, openingCancelled, staticObjectArgs);
|
|
}
|
|
|
|
KexiDialogBase *
|
|
KexiMainWindowImpl::openObject(KexiPart::Item* item, int viewMode, bool &openingCancelled,
|
|
TQMap<TQString,TQString>* staticObjectArgs, TQString* errorMessage)
|
|
{
|
|
if (!openingAllowed(item, viewMode)) {
|
|
if (errorMessage)
|
|
*errorMessage = i18n("opening is not allowed in \"data view/design view/text view\" mode",
|
|
"opening is not allowed in \"%1\" mode").arg(Kexi::nameForViewMode(viewMode));
|
|
openingCancelled = true;
|
|
return 0;
|
|
}
|
|
|
|
if (!d->prj || !item)
|
|
return 0;
|
|
KexiUtils::WaitCursor wait;
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
|
|
if (pendingType != Private::NoJob) {
|
|
openingCancelled = true;
|
|
return 0;
|
|
}
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( item );
|
|
#endif
|
|
openingCancelled = false;
|
|
|
|
bool needsUpdateViewGUIClient = true;
|
|
if (dlg) {
|
|
dlg->activate();
|
|
if (viewMode!=dlg->currentViewMode()) {
|
|
if (!switchToViewMode(viewMode))
|
|
return 0;
|
|
}
|
|
needsUpdateViewGUIClient = false;
|
|
}
|
|
else {
|
|
d->updatePropEditorVisibility(viewMode);
|
|
KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
|
|
//update tabs before opening
|
|
updateCustomPropertyPanelTabs(d->curDialog ? d->curDialog->part() : 0,
|
|
d->curDialog ? d->curDialog->currentViewMode() : Kexi::NoViewMode,
|
|
part, viewMode);
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->addItemToPendingDialogs(item, Private::DialogOpeningJob);
|
|
#endif
|
|
dlg = d->prj->openObject(this, *item, viewMode, staticObjectArgs);
|
|
}
|
|
|
|
if (!dlg || !activateWindow(dlg)) {
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog(item->identifier());
|
|
#endif
|
|
updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert
|
|
//js TODO: add error msg...
|
|
return 0;
|
|
}
|
|
|
|
if (needsUpdateViewGUIClient /*&& !userMode()*/) {
|
|
//view changed: switch to this view's gui client
|
|
KXMLGUIClient *viewClient=dlg->guiClient();
|
|
updateDialogViewGUIClient(viewClient);
|
|
if (d->curDialogViewGUIClient && !viewClient)
|
|
guiFactory()->removeClient(d->curDialogViewGUIClient);
|
|
d->curDialogViewGUIClient=viewClient; //remember
|
|
}
|
|
|
|
invalidateViewModeActions();
|
|
if (viewMode!=dlg->currentViewMode())
|
|
invalidateSharedActions();
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
d->removePendingDialog( dlg->id() );
|
|
|
|
//perform pending global action that was suspended:
|
|
if (!d->pendingDialogsExist()) {
|
|
d->executeActionWhenPendingJobsAreFinished();
|
|
}
|
|
#endif
|
|
return dlg;
|
|
}
|
|
|
|
KexiDialogBase *
|
|
KexiMainWindowImpl::openObjectFromNavigator(KexiPart::Item* item, int viewMode)
|
|
{
|
|
bool openingCancelled;
|
|
return openObjectFromNavigator(item, viewMode, openingCancelled);
|
|
}
|
|
|
|
KexiDialogBase *
|
|
KexiMainWindowImpl::openObjectFromNavigator(KexiPart::Item* item, int viewMode,
|
|
bool &openingCancelled)
|
|
{
|
|
if (!openingAllowed(item, viewMode)) {
|
|
openingCancelled = true;
|
|
return 0;
|
|
}
|
|
if (!d->prj || !item)
|
|
return 0;
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
|
|
if (pendingType!=Private::NoJob) {
|
|
openingCancelled = true;
|
|
return 0;
|
|
}
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( item );
|
|
#endif
|
|
openingCancelled = false;
|
|
if (dlg) {
|
|
if (activateWindow(dlg)) {//item->identifier())) {//just activate
|
|
invalidateViewModeActions();
|
|
return dlg;
|
|
}
|
|
}
|
|
//if DataViewMode is not supported, try Design, then Text mode (currently useful for script part)
|
|
KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
|
|
if (!part)
|
|
return 0;
|
|
if (viewMode == Kexi::DataViewMode && !(part->supportedViewModes() & Kexi::DataViewMode)) {
|
|
if (part->supportedViewModes() & Kexi::DesignViewMode)
|
|
return openObjectFromNavigator( item, Kexi::DesignViewMode, openingCancelled );
|
|
else if (part->supportedViewModes() & Kexi::TextViewMode)
|
|
return openObjectFromNavigator( item, Kexi::TextViewMode, openingCancelled );
|
|
}
|
|
//do the same as in openObject()
|
|
return openObject(item, viewMode, openingCancelled);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::closeObject(KexiPart::Item* item)
|
|
{
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
|
|
if (pendingType == Private::DialogClosingJob)
|
|
return true;
|
|
else if (pendingType == Private::DialogOpeningJob)
|
|
return cancelled;
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( item );
|
|
#endif
|
|
if (!dlg)
|
|
return cancelled;
|
|
return closeDialog(dlg);
|
|
}
|
|
|
|
bool KexiMainWindowImpl::newObject( KexiPart::Info *info, bool& openingCancelled )
|
|
{
|
|
if (userMode()) {
|
|
openingCancelled = true;
|
|
return false;
|
|
}
|
|
openingCancelled = false;
|
|
if (!d->prj || !info)
|
|
return false;
|
|
KexiPart::Part *part = Kexi::partManager().partForMimeType(info->mimeType());
|
|
if(!part)
|
|
return false;
|
|
|
|
#ifdef KEXI_ADD_CUSTOM_OBJECT_CREATION
|
|
# include "keximainwindowimpl_customobjcreation.h"
|
|
#endif
|
|
|
|
KexiPart::Item *it = d->prj->createPartItem(info); //this, *item, viewMode);
|
|
if (!it) {
|
|
//js: todo: err
|
|
return false;
|
|
}
|
|
|
|
if (!it->neverSaved()) //only add stored objects to the browser
|
|
d->nav->addItem(*it);
|
|
return openObject(it, Kexi::DesignViewMode, openingCancelled);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::removeObject( KexiPart::Item *item, bool dontAsk )
|
|
{
|
|
if (userMode())
|
|
return cancelled;
|
|
if (!d->prj || !item)
|
|
return false;
|
|
|
|
KexiPart::Part *part = Kexi::partManager().partForMimeType(item->mimeType());
|
|
if (!part)
|
|
return false;
|
|
|
|
if (!dontAsk) {
|
|
if (KMessageBox::No == KMessageBox::warningYesNo(this,
|
|
"<p>"+i18n("Do you want to permanently delete:\n"
|
|
"%1\n"
|
|
"If you click \"Delete\", you will not be able to undo the deletion.")
|
|
.arg( "</p><p>"+part->instanceCaption()+" \""+ item->name() + "\"?</p>" ),
|
|
0, KGuiItem(i18n("Delete"), "edit-delete"), KStdGuiItem::no()))
|
|
return cancelled;
|
|
}
|
|
|
|
//also close 'print setup' dialog for this item, if any
|
|
tristate res;
|
|
// int printedObjectID = 0;
|
|
// if (d->pageSetupDialogItemID2dataItemID_map.contains(item->identifier()))
|
|
// printedObjectID = d->pageSetupDialogItemID2dataItemID_map[ item->identifier() ];
|
|
KexiDialogBase * pageSetupDlg = d->pageSetupDialogs[ item->identifier() ];
|
|
const bool oldInsideCloseDialog = d->insideCloseDialog;
|
|
d->insideCloseDialog = false;
|
|
res = closeDialog(pageSetupDlg);
|
|
d->insideCloseDialog = oldInsideCloseDialog;
|
|
if (!res || ~res) {
|
|
return res;
|
|
}
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
|
|
if (pendingType!=Private::NoJob) {
|
|
return cancelled;
|
|
}
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( item );
|
|
#endif
|
|
|
|
if (dlg) {//close existing window
|
|
// if (!dlg->tryClose(true))
|
|
const bool tmp = d->forceDialogClosing;
|
|
/*const bool remove_on_closing = */dlg->partItem()->neverSaved();
|
|
d->forceDialogClosing = true;
|
|
res = closeDialog(dlg);
|
|
d->forceDialogClosing = tmp; //restore
|
|
if (!res || ~res) {
|
|
return res;
|
|
}
|
|
// if (remove_on_closing) //already removed
|
|
// return true;
|
|
// if (!dlg->close(true))
|
|
// return true; //ok - close cancelled
|
|
}
|
|
|
|
//in case the dialog is a 'print setup' dialog, also update d->pageSetupDialogs
|
|
int dataItemID = d->pageSetupDialogItemID2dataItemID_map[item->identifier()];
|
|
d->pageSetupDialogItemID2dataItemID_map.remove(item->identifier());
|
|
d->pageSetupDialogs.take( dataItemID );
|
|
|
|
if (!d->prj->removeObject(this, *item)) {
|
|
//TODO(js) better msg
|
|
showSorryMessage( i18n("Could not remove object.") );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void KexiMainWindowImpl::renameObject( KexiPart::Item *item, const TQString& _newName, bool &success )
|
|
{
|
|
if (userMode()) {
|
|
success = false;
|
|
return;
|
|
}
|
|
d->pendingDialogsExist();
|
|
TQString newName = _newName.stripWhiteSpace();
|
|
if (newName.isEmpty()) {
|
|
showSorryMessage( i18n("Could not set empty name for this object.") );
|
|
success = false;
|
|
return;
|
|
}
|
|
enableMessages(false); //to avoid double messages
|
|
const bool res = d->prj->renameObject(this, *item, newName);
|
|
enableMessages(true);
|
|
if (!res) {
|
|
showErrorMessage( d->prj, i18n("Renaming object \"%1\" failed.").arg(newName) );
|
|
success = false;
|
|
return;
|
|
}
|
|
d->pendingDialogsExist();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotObjectRenamed(const KexiPart::Item &item, const TQCString& /*oldName*/)
|
|
{
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( &item, pendingType );
|
|
if (pendingType!=Private::NoJob)
|
|
return;
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( &item );
|
|
#endif
|
|
if (!dlg)
|
|
return;
|
|
|
|
//change item
|
|
dlg->updateCaption();
|
|
if (static_cast<KexiDialogBase*>(d->curDialog)==dlg)//optionally, update app. caption
|
|
updateAppCaption();
|
|
}
|
|
|
|
int KexiMainWindowImpl::generatePrivateID()
|
|
{
|
|
return --d->privateIDCounter;
|
|
}
|
|
|
|
void KexiMainWindowImpl::acceptPropertySetEditing()
|
|
{
|
|
if (d->propEditor)
|
|
d->propEditor->editor()->acceptInput();
|
|
}
|
|
|
|
void KexiMainWindowImpl::propertySetSwitched(KexiDialogBase *dlg, bool force,
|
|
bool preservePrevSelection, const TQCString& propertyToSelect)
|
|
{
|
|
kdDebug() << "KexiMainWindowImpl::propertySetSwitched() d->curDialog: "
|
|
<< (d->curDialog ? d->curDialog->caption() : TQString("NULL")) << " dlg: " << (dlg ? dlg->caption() : TQString("NULL"))<< endl;
|
|
if ((KexiDialogBase*)d->curDialog!=dlg) {
|
|
d->propBuffer = 0; //we'll need to move to another prop. set
|
|
return;
|
|
}
|
|
if (d->propEditor) {
|
|
KoProperty::Set *newBuf = d->curDialog ? d->curDialog->propertySet() : 0;
|
|
if (!newBuf || (force || static_cast<KoProperty::Set*>(d->propBuffer) != newBuf)) {
|
|
d->propBuffer = newBuf;
|
|
if (preservePrevSelection) {
|
|
if (propertyToSelect.isEmpty())
|
|
d->propEditor->editor()->changeSet( d->propBuffer, preservePrevSelection );
|
|
else
|
|
d->propEditor->editor()->changeSet( d->propBuffer, propertyToSelect );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotDirtyFlagChanged(KexiDialogBase* dlg)
|
|
{
|
|
KexiPart::Item *item = dlg->partItem();
|
|
//update text in navigator and app. caption
|
|
if(!userMode())
|
|
d->nav->updateItemName( *item, dlg->dirty() );
|
|
|
|
invalidateActions();
|
|
updateAppCaption();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotMdiModeHasBeenChangedTo(KMdi::MdiMode)
|
|
{
|
|
//after switching to other MDI mode, pointer to current dialog needs to be updated
|
|
activateFirstWin();
|
|
activeWindowChanged(activeWindow());
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotTipOfTheDay()
|
|
{
|
|
//todo
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotImportantInfo()
|
|
{
|
|
importantInfo(false);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotStartFeedbackAgent()
|
|
{
|
|
#ifndef KEXI_NO_FEEDBACK_AGENT
|
|
#ifdef FEEDBACK_CLASS
|
|
const TDEAboutData* about = TDEApplication::kApplication()->aboutData();
|
|
FEEDBACK_CLASS* wizard = new FEEDBACK_CLASS( about->programName(),
|
|
about->version(), 0, 0, 0, FEEDBACK_CLASS::AllPages );
|
|
|
|
if ( wizard->exec() )
|
|
{
|
|
TDEApplication::kApplication()->invokeMailer( "kexi-reports-dummy@kexi.org",
|
|
TQString(), TQString(),
|
|
about->appName() + TQCString( " [feedback]" ),
|
|
wizard->feedbackDocument().toString( 2 ).local8Bit() );
|
|
}
|
|
|
|
delete wizard;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::importantInfo(bool /*onStartup*/)
|
|
{
|
|
#if 0
|
|
if (onStartup && !d->showImportantInfoOnStartup)
|
|
return;
|
|
|
|
TQString key = TQString("showImportantInfo %1").arg(KEXI_VERSION_STRING);
|
|
d->config->setGroup("Startup");
|
|
bool show = d->config->readBoolEntry(key,true);
|
|
|
|
if (show || !onStartup) { //if !onStartup - dialog is always shown
|
|
d->config->setGroup("TipOfDay");
|
|
if (!d->config->hasKey("RunOnStart"))
|
|
d->config->writeEntry("RunOnStart",true);
|
|
|
|
TQString lang = TDEGlobal::locale()->language();
|
|
TQString fname = locate("data", TQString("kexi/readme_")+lang);
|
|
if (fname.isEmpty())//back to default
|
|
fname = locate("data", "kexi/readme_en");
|
|
KTipDialog tipDialog(new KTipDatabase(TQString()), 0);
|
|
tipDialog.setCaption(i18n("Important Information"));
|
|
TQObjectList *l = tipDialog.queryList( "KPushButton" );//hack: hide <- -> buttons
|
|
int i=0;
|
|
for (TQObjectListIt it( *l ); it.current() && i<2; ++it, i++ )
|
|
static_cast<KPushButton*>(it.current())->hide();
|
|
TQFile f(fname);
|
|
if ( f.open( IO_ReadOnly ) ) {
|
|
TQTextStream ts(&f);
|
|
ts.setCodec( TDEGlobal::locale()->codecForEncoding() );
|
|
TQTextBrowser *tb = KexiUtils::findFirstChild<KTextBrowser>(&tipDialog,"KTextBrowser");
|
|
if (tb) {
|
|
tb->setText( TQString("<qt>%1</qt>").arg(ts.read()) );
|
|
}
|
|
f.close();
|
|
}
|
|
|
|
tipDialog.adjustSize();
|
|
TQRect desk = TQApplication::desktop()->screenGeometry( TQApplication::desktop()->screenNumber(this) );
|
|
tipDialog.resize( TQMAX(tipDialog.width(),desk.width()*3/5), TQMAX(tipDialog.height(),desk.height()*3/5) );
|
|
KDialog::centerOnScreen(&tipDialog);
|
|
tipDialog.setModal ( true );
|
|
tipDialog.exec();
|
|
//a hack: get user's settings
|
|
d->config->setGroup("TipOfDay");
|
|
show = d->config->readBoolEntry("RunOnStart", show);
|
|
}
|
|
|
|
//write our settings back
|
|
d->config->setGroup("Startup");
|
|
d->config->writeEntry(key,show);
|
|
d->showImportantInfoOnStartup = false;
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotOptionsEnableForms(bool show, bool noMessage)
|
|
{
|
|
Q_UNUSED(noMessage);
|
|
Kexi::tempShowForms() = show;
|
|
}
|
|
|
|
bool KexiMainWindowImpl::userMode() const
|
|
{
|
|
return d->userMode;
|
|
}
|
|
|
|
bool
|
|
KexiMainWindowImpl::initUserMode(KexiProjectData *projectData)
|
|
{
|
|
// Kexi::tempShowForms() = true;
|
|
// Kexi::tempShowReports() = true;
|
|
// Kexi::tempShowMacros() = true;
|
|
// Kexi::tempShowScripts() = true;
|
|
if(!projectData)
|
|
return false;
|
|
|
|
createKexiProject(projectData); //initialize project
|
|
// d->prj->setFinal(true); //announce that we are in fianl mode
|
|
|
|
tristate res = d->prj->open(); //try to open database
|
|
if (!res || ~res) {
|
|
delete d->prj;
|
|
d->prj = 0;
|
|
return false;
|
|
}
|
|
|
|
#if 0 //todo reenable; autoopen objects are handled elsewhere
|
|
KexiDB::TableSchema *sch = d->prj->dbConnection()->tableSchema("kexi__final");
|
|
TQString err_msg = i18n("Could not start project \"%1\" in Final Mode.")
|
|
.arg(static_cast<KexiDB::SchemaData*>(projectData)->name());
|
|
if(!sch)
|
|
{
|
|
hide();
|
|
showErrorMessage( err_msg, i18n("No Final Mode data found.") );
|
|
return false;
|
|
}
|
|
|
|
KexiDB::Cursor *c = d->prj->dbConnection()->executeQuery(*sch);
|
|
if(!c)
|
|
{
|
|
hide();
|
|
showErrorMessage( err_msg, i18n("Error reading Final Mode data.") );
|
|
return false;
|
|
}
|
|
|
|
TQString startupPart;
|
|
TQString startupItem;
|
|
while(c->moveNext())
|
|
{
|
|
kdDebug() << "KexiMainWinImpl::initFinalMode(): property: [" << c->value(1).toString() << "] " << c->value(2).toString() << endl;
|
|
if(c->value(1).toString() == "startup-part")
|
|
startupPart = c->value(2).toString();
|
|
else if(c->value(1).toString() == "startup-item")
|
|
startupItem = c->value(2).toString();
|
|
else if(c->value(1).toString() == "mainxmlui")
|
|
setXML(c->value(2).toString());
|
|
}
|
|
d->prj->dbConnection()->deleteCursor(c);
|
|
|
|
kdDebug() << "KexiMainWinImpl::initFinalMode(): part: " << startupPart << endl;
|
|
kdDebug() << "KexiMainWinImpl::initFinalMode(): item: " << startupItem << endl;
|
|
|
|
initActions();
|
|
initUserActions();
|
|
guiFactory()->addClient(this);
|
|
setStandardToolBarMenuEnabled(false);
|
|
setHelpMenuEnabled(false);
|
|
|
|
KexiPart::Info *i = Kexi::partManager().infoForMimeType(startupPart.latin1());
|
|
if (!i) {
|
|
hide();
|
|
showErrorMessage( err_msg, i18n("Specified plugin does not exist.") );
|
|
return false;
|
|
}
|
|
|
|
Kexi::partManager().part(i);
|
|
KexiPart::Item *item = d->prj->item(i, startupItem);
|
|
bool openingCancelled;
|
|
if(!openObject(item, Kexi::DataViewMode, openingCancelled) && !openingCancelled) {
|
|
hide();
|
|
showErrorMessage( err_msg, i18n("Specified object could not be opened.") );
|
|
return false;
|
|
}
|
|
|
|
TQWidget::setCaption("MyApp");//TODO
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void
|
|
KexiMainWindowImpl::initUserActions()
|
|
{
|
|
#if 0 //unused for now
|
|
KexiDB::Cursor *c = d->prj->dbConnection()->executeQuery("SELECT p_id, name, text, icon, method, arguments FROM kexi__useractions WHERE scope = 0");
|
|
if(!c)
|
|
return;
|
|
|
|
while(c->moveNext())
|
|
{
|
|
KexiUserAction::fromCurrentRecord(this, actionCollection(), c);
|
|
}
|
|
d->prj->dbConnection()->deleteCursor(c);
|
|
/*
|
|
KexiUserAction *a1 = new KexiUserAction(this, actionCollection(), "user_dataview", "Change to dataview", "table");
|
|
Arguments args;
|
|
args.append(TQVariant("kexi/table"));
|
|
args.append(TQVariant("persons"));
|
|
a1->setMethod(KexiUserAction::OpenObject, args);
|
|
*/
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotToolsProjectMigration()
|
|
{
|
|
showProjectMigrationWizard(TQString(), TQString());
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotToolsCompactDatabase()
|
|
{
|
|
KexiProjectData *data = 0;
|
|
KexiDB::Driver *drv = 0;
|
|
const bool projectWasOpened = d->prj;
|
|
|
|
if (!d->prj) {
|
|
KexiStartupDialog dlg(
|
|
KexiStartupDialog::OpenExisting, 0, Kexi::connset(), Kexi::recentProjects(),
|
|
this, "KexiOpenDialog");
|
|
|
|
if (dlg.exec()!=TQDialog::Accepted)
|
|
return;
|
|
|
|
if (dlg.selectedFileName().isEmpty()) {
|
|
//! @todo add support for server based if needed?
|
|
return;
|
|
}
|
|
KexiDB::ConnectionData cdata;
|
|
cdata.setFileName( dlg.selectedFileName() );
|
|
|
|
//detect driver name for the selected file
|
|
KexiStartupData::Import detectedImportAction;
|
|
tristate res = KexiStartupHandler::detectActionForFile(
|
|
detectedImportAction, cdata.driverName,
|
|
"" /*suggestedDriverName*/, cdata.fileName(), 0,
|
|
KexiStartupHandler::SkipMessages | KexiStartupHandler::ThisIsAProjectFile
|
|
| KexiStartupHandler::DontConvert);
|
|
|
|
if (true==res && !detectedImportAction)
|
|
drv = Kexi::driverManager().driver( cdata.driverName );
|
|
if (!drv || !(drv->features() & KexiDB::Driver::CompactingDatabaseSupported)) {
|
|
KMessageBox::information(this, "<qt>"+
|
|
i18n("Compacting database file <nobr>\"%1\"</nobr> is not supported.")
|
|
.arg(TQDir::convertSeparators(cdata.fileName())));
|
|
return;
|
|
}
|
|
data = new KexiProjectData( cdata, cdata.fileName() );
|
|
}
|
|
else {
|
|
//sanity
|
|
if ( !(d->prj && d->prj->dbConnection()
|
|
&& (d->prj->dbConnection()->driver()->features() & KexiDB::Driver::CompactingDatabaseSupported) ))
|
|
return;
|
|
|
|
if (KMessageBox::Continue != KMessageBox::warningContinueCancel(this,
|
|
i18n("The current project has to be closed before compacting the database. "
|
|
"It will be open again after compacting.\n\nDo you want to continue?")))
|
|
return;
|
|
|
|
data = new KexiProjectData(*d->prj->data()); // a copy
|
|
drv = d->prj->dbConnection()->driver();
|
|
const tristate res = closeProject();
|
|
if (~res || !res) {
|
|
delete data;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!drv->adminTools().vacuum(*data->connectionData(), data->databaseName())) {
|
|
//err msg
|
|
showErrorMessage( &drv->adminTools() );
|
|
}
|
|
|
|
if (projectWasOpened)
|
|
openProject(*data);
|
|
delete data;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::showProjectMigrationWizard(
|
|
const TQString& mimeType, const TQString& databaseName, const KexiDB::ConnectionData *cdata)
|
|
{
|
|
//pass arguments
|
|
TQMap<TQString,TQString> args;
|
|
args.insert("mimeType", mimeType);
|
|
args.insert("databaseName", databaseName);
|
|
if (cdata) { //pass ConnectionData serialized as a string...
|
|
TQString str;
|
|
KexiUtils::serializeMap( KexiDB::toMap( *cdata ), str );
|
|
args.insert("connectionData", str);
|
|
}
|
|
|
|
TQDialog *dlg = KexiInternalPart::createModalDialogInstance("migration", this, this, 0, &args);
|
|
if (!dlg)
|
|
return false; //error msg has been shown by KexiInternalPart
|
|
|
|
const int result = dlg->exec();
|
|
delete dlg;
|
|
//raise();
|
|
if (result!=TQDialog::Accepted)
|
|
return cancelled;
|
|
|
|
//open imported project in a new Kexi instance
|
|
TQString destinationDatabaseName( args["destinationDatabaseName"] );
|
|
TQString fileName, destinationConnectionShortcut, dbName;
|
|
if (!destinationDatabaseName.isEmpty()) {
|
|
if (args.contains("destinationConnectionShortcut")) {
|
|
// server-based
|
|
destinationConnectionShortcut = args["destinationConnectionShortcut"];
|
|
}
|
|
else {
|
|
// file-based
|
|
fileName = destinationDatabaseName;
|
|
destinationDatabaseName = TQString();
|
|
}
|
|
tristate res = openProject(fileName, destinationConnectionShortcut,
|
|
destinationDatabaseName);
|
|
raise();
|
|
return res;
|
|
// KexiDB::ConnectionData *connData = new KexiDB::ConnectionData();
|
|
// KexiDB::fromMap( KexiUtils::deserializeMap( args["destinationConnectionData"] ), *connData );
|
|
// return openProject(destinationFileName, 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::executeItem(KexiPart::Item* item)
|
|
{
|
|
KexiPart::Info *info = item ? Kexi::partManager().infoForMimeType(item->mimeType()) : 0;
|
|
if ( (! info) || (! info->isExecuteSupported()) )
|
|
return false;
|
|
KexiPart::Part *part = Kexi::partManager().part(info);
|
|
if (!part)
|
|
return false;
|
|
return part->execute(item);
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotProjectImportDataTable()
|
|
{
|
|
//! @todo allow data appending (it is not possible now)
|
|
if (userMode())
|
|
return;
|
|
TQMap<TQString,TQString> args;
|
|
args.insert("sourceType", "file");
|
|
TQDialog *dlg = KexiInternalPart::createModalDialogInstance(
|
|
"csv_importexport", "KexiCSVImportDialog", this, this, 0, &args);
|
|
if (!dlg)
|
|
return; //error msg has been shown by KexiInternalPart
|
|
dlg->exec();
|
|
delete dlg;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::executeCustomActionForObject(KexiPart::Item* item,
|
|
const TQString& actionName)
|
|
{
|
|
if (actionName == "exportToCSV")
|
|
return exportItemAsDataTable(item);
|
|
else if (actionName == "copyToClipboardAsCSV")
|
|
return copyItemToClipboardAsDataTable(item);
|
|
|
|
kexiwarn << "KexiMainWindowImpl::executeCustomActionForObject(): no such action: "
|
|
<< actionName << endl;
|
|
return false;
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::exportItemAsDataTable(KexiPart::Item* item)
|
|
{
|
|
if (!item)
|
|
return false;
|
|
//! @todo: check if changes to this are saved, if not: ask for saving
|
|
//! @todo: accept row changes...
|
|
|
|
TQMap<TQString,TQString> args;
|
|
args.insert("destinationType", "file");
|
|
args.insert("itemId", TQString::number(item->identifier()));
|
|
TQDialog *dlg = KexiInternalPart::createModalDialogInstance(
|
|
"csv_importexport", "KexiCSVExportWizard", this, this, 0, &args);
|
|
if (!dlg)
|
|
return false; //error msg has been shown by KexiInternalPart
|
|
int result = dlg->exec();
|
|
delete dlg;
|
|
return result == TQDialog::Rejected ? cancelled : true;
|
|
}
|
|
|
|
bool KexiMainWindowImpl::printItem(KexiPart::Item* item, const TQString& titleText)
|
|
{
|
|
return printItem(item, KexiSimplePrintingSettings::load(), titleText);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::printItem(KexiPart::Item* item)
|
|
{
|
|
return printItem(item, TQString());
|
|
}
|
|
|
|
bool KexiMainWindowImpl::printItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings,
|
|
const TQString& titleText)
|
|
{
|
|
//! @todo: check if changes to this object's design are saved, if not: ask for saving
|
|
//! @todo: accept row changes...
|
|
KexiSimplePrintingCommand cmd(this, item->identifier());
|
|
//modal
|
|
return cmd.print(settings, titleText);
|
|
}
|
|
|
|
bool KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item, const TQString& titleText, bool reload)
|
|
{
|
|
return printPreviewForItem(item, KexiSimplePrintingSettings::load(), titleText, reload);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item)
|
|
{
|
|
return printPreviewForItem(item, TQString(),
|
|
//! @todo store cached row data?
|
|
true/*reload*/);
|
|
}
|
|
|
|
bool KexiMainWindowImpl::printPreviewForItem(KexiPart::Item* item,
|
|
const KexiSimplePrintingSettings& settings, const TQString& titleText, bool reload)
|
|
{
|
|
//! @todo: check if changes to this object's design are saved, if not: ask for saving
|
|
//! @todo: accept row changes...
|
|
KexiSimplePrintingCommand* cmd = d->openedCustomObjectsForItem<KexiSimplePrintingCommand>(
|
|
item, "KexiSimplePrintingCommand");
|
|
if (!cmd) {
|
|
d->addOpenedCustomObjectForItem(
|
|
item,
|
|
cmd = new KexiSimplePrintingCommand(this, item->identifier()),
|
|
"KexiSimplePrintingCommand"
|
|
);
|
|
}
|
|
return cmd->showPrintPreview(settings, titleText, reload);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::showPageSetupForItem(KexiPart::Item* item)
|
|
{
|
|
//! @todo: check if changes to this object's design are saved, if not: ask for saving
|
|
//! @todo: accept row changes...
|
|
return printActionForItem(item, PageSetupForItem);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::printActionForItem(KexiPart::Item* item, PrintActionType action)
|
|
{
|
|
if (!item)
|
|
return false;
|
|
KexiPart::Info *info = Kexi::partManager().infoForMimeType( item->mimeType() );
|
|
if (!info->isPrintingSupported())
|
|
return false;
|
|
|
|
KexiDialogBase *printingDialog = d->pageSetupDialogs[ item->identifier() ];
|
|
if (printingDialog) {
|
|
if (!activateWindow(printingDialog))
|
|
return false;
|
|
if (action == PreviewItem || action == PrintItem) {
|
|
TQTimer::singleShot(0,printingDialog->selectedView(),
|
|
(action == PreviewItem) ? TQT_SLOT(printPreview()) : TQT_SLOT(print()));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#ifndef KEXI_NO_PENDING_DIALOGS
|
|
Private::PendingJobType pendingType;
|
|
KexiDialogBase *dlg = d->openedDialogFor( item, pendingType );
|
|
if (pendingType!=Private::NoJob)
|
|
return cancelled;
|
|
#else
|
|
KexiDialogBase *dlg = d->openedDialogFor( item );
|
|
#endif
|
|
|
|
if (dlg) {
|
|
// accept row changes
|
|
TQWidget *prevFocusWidget = focusWidget();
|
|
dlg->setFocus();
|
|
d->action_data_save_row->activate();
|
|
if (prevFocusWidget)
|
|
prevFocusWidget->setFocus();
|
|
|
|
// opened: check if changes made to this dialog are saved, if not: ask for saving
|
|
if (dlg->neverSaved()) //sanity check
|
|
return false;
|
|
if (dlg->dirty()) {
|
|
KGuiItem saveChanges( KStdGuiItem::save() );
|
|
saveChanges.setToolTip(i18n("Save changes"));
|
|
saveChanges.setWhatsThis(
|
|
i18n( "Pressing this button will save all recent changes made in \"%1\" object." )
|
|
.arg(item->name()) );
|
|
KGuiItem doNotSave( KStdGuiItem::no() );
|
|
doNotSave.setWhatsThis(
|
|
i18n( "Pressing this button will ignore all unsaved changes made in \"%1\" object." )
|
|
.arg(dlg->partItem()->name()) );
|
|
|
|
TQString question;
|
|
if (action == PrintItem)
|
|
question = i18n("Do you want to save changes before printing?");
|
|
else if (action == PreviewItem)
|
|
question = i18n("Do you want to save changes before making print preview?");
|
|
else if (action == PageSetupForItem)
|
|
question = i18n("Do you want to save changes before showing page setup?");
|
|
else
|
|
return false;
|
|
|
|
const int questionRes = KMessageBox::warningYesNoCancel( this,
|
|
"<p>"+dlg->part()->i18nMessage("Design of object \"%1\" has been modified.", dlg)
|
|
.arg(item->name()) + "</p><p>" + question + "</p>",
|
|
TQString(),
|
|
saveChanges,
|
|
doNotSave);
|
|
if (KMessageBox::Cancel == questionRes)
|
|
return cancelled;
|
|
if (KMessageBox::Yes == questionRes) {
|
|
tristate savingRes = saveObject( dlg, TQString(), true /*dontAsk*/ );
|
|
if (true != savingRes)
|
|
return savingRes;
|
|
}
|
|
}
|
|
}
|
|
KexiPart::Part * printingPart = Kexi::partManager().partForMimeType("kexi/simpleprinting");
|
|
if (!printingPart)
|
|
printingPart = new KexiSimplePrintingPart(); //hardcoded as there're no .desktop file
|
|
KexiPart::Item* printingPartItem = d->prj->createPartItem(
|
|
printingPart, item->name() //<-- this will look like "table1 : printing" on the window list
|
|
);
|
|
TQMap<TQString,TQString> staticObjectArgs;
|
|
staticObjectArgs["identifier"] = TQString::number(item->identifier());
|
|
if (action == PrintItem)
|
|
staticObjectArgs["action"] = "print";
|
|
else if (action == PreviewItem)
|
|
staticObjectArgs["action"] = "printPreview";
|
|
else if (action == PageSetupForItem)
|
|
staticObjectArgs["action"] = "pageSetup";
|
|
else
|
|
return false;
|
|
bool openingCancelled;
|
|
printingDialog = openObject(printingPartItem, Kexi::DesignViewMode,
|
|
openingCancelled, &staticObjectArgs);
|
|
if (openingCancelled)
|
|
return cancelled;
|
|
if (!printingDialog) //sanity
|
|
return false;
|
|
d->pageSetupDialogs.insert(item->identifier(), printingDialog);
|
|
d->pageSetupDialogItemID2dataItemID_map.insert(
|
|
printingDialog->partItem()->identifier(), item->identifier());
|
|
|
|
return true;
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditCopySpecialDataTable()
|
|
{
|
|
KexiPart::Item* item = d->nav->selectedPartItem();
|
|
if (item)
|
|
exportItemAsDataTable(item);
|
|
}
|
|
|
|
tristate KexiMainWindowImpl::copyItemToClipboardAsDataTable(KexiPart::Item* item)
|
|
{
|
|
if (!item)
|
|
return false;
|
|
|
|
TQMap<TQString,TQString> args;
|
|
args.insert("destinationType", "clipboard");
|
|
args.insert("itemId", TQString::number(item->identifier()));
|
|
TQDialog *dlg = KexiInternalPart::createModalDialogInstance(
|
|
"csv_importexport", "KexiCSVExportWizard", this, this, 0, &args);
|
|
if (!dlg)
|
|
return false; //error msg has been shown by KexiInternalPart
|
|
const int result = dlg->exec();
|
|
delete dlg;
|
|
return result == TQDialog::Rejected ? cancelled : true;
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditPasteSpecialDataTable()
|
|
{
|
|
//! @todo allow data appending (it is not possible now)
|
|
if (userMode())
|
|
return;
|
|
TQMap<TQString,TQString> args;
|
|
args.insert("sourceType", "clipboard");
|
|
TQDialog *dlg = KexiInternalPart::createModalDialogInstance(
|
|
"csv_importexport", "KexiCSVImportDialog", this, this, 0, &args);
|
|
if (!dlg)
|
|
return; //error msg has been shown by KexiInternalPart
|
|
dlg->exec();
|
|
delete dlg;
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditFind()
|
|
{
|
|
// KexiViewBase *view = d->currentViewSupportingAction("edit_findnext");
|
|
KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
|
|
if (!iface)
|
|
return;
|
|
d->updateFindDialogContents(true/*create if does not exist*/);
|
|
d->findDialog()->setReplaceMode(false);
|
|
|
|
d->findDialog()->show();
|
|
d->findDialog()->setActiveWindow();
|
|
d->findDialog()->raise();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditFind(bool next)
|
|
{
|
|
KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
|
|
if (!iface)
|
|
return;
|
|
tristate res = iface->find(
|
|
d->findDialog()->valueToFind(), d->findDialog()->options(), next);
|
|
if (~res)
|
|
return;
|
|
d->findDialog()->updateMessage( true == res );
|
|
//! @todo result
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditFindNext()
|
|
{
|
|
slotEditFind( true );
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditFindPrevious()
|
|
{
|
|
slotEditFind( false );
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditReplace()
|
|
{
|
|
KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
|
|
if (!iface)
|
|
return;
|
|
d->updateFindDialogContents(true/*create if does not exist*/);
|
|
d->findDialog()->setReplaceMode(true);
|
|
//! @todo slotEditReplace()
|
|
d->findDialog()->show();
|
|
d->findDialog()->setActiveWindow();
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditReplaceNext()
|
|
{
|
|
slotEditReplace( false );
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditReplace(bool all)
|
|
{
|
|
KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface();
|
|
if (!iface)
|
|
return;
|
|
//! @todo add question: "Do you want to replace every occurence of \"%1\" with \"%2\"?
|
|
//! You won't be able to undo this." + "Do not ask again".
|
|
tristate res = iface->findNextAndReplace(
|
|
d->findDialog()->valueToFind(), d->findDialog()->valueToReplaceWith(),
|
|
d->findDialog()->options(), all);
|
|
d->findDialog()->updateMessage( true == res );
|
|
//! @todo result
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotEditReplaceAll()
|
|
{
|
|
slotEditReplace( true );
|
|
}
|
|
|
|
void KexiMainWindowImpl::addWindow( KMdiChildView* pView, int flags )
|
|
{
|
|
//maximize this window, if it's
|
|
//!@todo Certain windows' sizes, e.g. forms could have own size configation specified!
|
|
//! Query for this, and if so: give up.
|
|
if (d->maximizeFirstOpenedChildFrm) {
|
|
flags |= KMdi::Maximize;
|
|
d->maximizeFirstOpenedChildFrm = false;
|
|
}
|
|
KexiMainWindow::addWindow( pView, flags );
|
|
}
|
|
|
|
/// TMP (until there's true template support)
|
|
void KexiMainWindowImpl::slotGetNewStuff()
|
|
{
|
|
#ifdef HAVE_TDENEWSTUFF
|
|
if(!d->newStuff)
|
|
d->newStuff = new KexiNewStuff(this);
|
|
d->newStuff->download();
|
|
|
|
//KNS::DownloadDialog::open(newstuff->customEngine(), "kexi/template");
|
|
#endif
|
|
}
|
|
|
|
void KexiMainWindowImpl::highlightObject(const TQCString& mime, const TQCString& name)
|
|
{
|
|
slotViewNavigator();
|
|
if (!d->prj)
|
|
return;
|
|
KexiPart::Item *item = d->prj->itemForMimeType(mime, name);
|
|
if (!item)
|
|
return;
|
|
if (d->nav) {
|
|
d->nav->selectItem(*item);
|
|
}
|
|
}
|
|
|
|
void KexiMainWindowImpl::slotPartItemSelectedInNavigator(KexiPart::Item* item)
|
|
{
|
|
Q_UNUSED(item);
|
|
}
|
|
|
|
#include "keximainwindowimpl.moc"
|