/* This file is part of the KDE project Copyright (C) 2003-2007 Jaroslaw Staniek 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 "KexiStartup.h" #ifdef TQ_WS_WIN # include "KexiStartup_p_win.h" #else # include "KexiStartup_p.h" #endif #include "kexiproject.h" #include "kexiprojectdata.h" #include "kexiprojectset.h" #include "kexiguimsghandler.h" #include #include #include "KexiStartupDialog.h" #include "KexiConnSelector.h" #include "KexiProjectSelectorBase.h" #include "KexiProjectSelector.h" #include "KexiNewProjectWizard.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Kexi { static KStaticDeleter Kexi_startupHandlerDeleter; KexiStartupHandler* _startupHandler = 0; KexiStartupHandler& startupHandler() { if (!_startupHandler) Kexi_startupHandlerDeleter.setObject( _startupHandler, new KexiStartupHandler() ); return *_startupHandler; } } //--------------------------------- //! @internal class KexiStartupHandlerPrivate { public: KexiStartupHandlerPrivate() : passwordDialog(0)//, showConnectionDetailsExecuted(false) , shortcutFile(0), connShortcutFile(0), connDialog(0), startupDialog(0) { } ~KexiStartupHandlerPrivate() { delete passwordDialog; delete connDialog; delete startupDialog; } KexiDBPasswordDialog* passwordDialog; // bool showConnectionDetailsExecuted : 1; KexiDBShortcutFile *shortcutFile; KexiDBConnShortcutFile *connShortcutFile; KexiDBConnectionDialog *connDialog; TQString shortcutFileGroupKey; KexiStartupDialog *startupDialog; }; //--------------------------------- static bool stripQuotes(const TQString &item, TQString &name) { if (item.left(1)=="\"" && item.right(1)=="\"") { name = item.mid(1, item.length()-2); return true; } name = item; return false; } void updateProgressBar(KProgressDialog *pd, char *buffer, int buflen) { char *p = buffer; TQCString line(80); for (int i=0; i='0' && *p<='9'; j++, i++, p++) line+=TQChar(*p).latin1(); --i; --p; int percent = line.toInt(&ok); if (ok && percent>=0 && percent<=100 && pd->progressBar()->progress()progressBar()->setProgress(percent); tqApp->processEvents(100); } } } } //--------------------------------- KexiDBPasswordDialog::KexiDBPasswordDialog(TQWidget *parent, KexiDB::ConnectionData& cdata, bool showDetailsButton) : KPasswordDialog( KPasswordDialog::Password, false/*keep*/, showDetailsButton ? (int)KDialogBase::User1 : 0, parent ) , m_cdata(&cdata) , m_showConnectionDetailsRequested(false) { TQString msg = "

" + i18n("Opening database") + "

" + i18n("Please enter the password.") + "

"; /* msg += cdata.userName.isEmpty() ? "

"+i18n("Please enter the password.") : "

"+i18n("Please enter the password for user.").arg(""+cdata.userName+"");*/ TQString srv = cdata.serverInfoString(false); if (srv.isEmpty() || srv.lower()=="localhost") srv = i18n("local database server"); msg += ("

"+i18n("Database server: %1").arg(TQString("")+srv+"")+"

"); TQString usr; if (cdata.userName.isEmpty()) usr = i18n("unspecified user", "(unspecified)"); else usr = cdata.userName; msg += ("

"+i18n("Username: %1").arg(usr)+"

"); setPrompt( msg ); if (showDetailsButton) { connect( this, TQT_SIGNAL(user1Clicked()), this, TQT_SLOT(slotShowConnectionDetails()) ); setButtonText(KDialogBase::User1, i18n("&Details")+ " >>"); } setButtonOK(KGuiItem(i18n("&Open"), "fileopen")); } KexiDBPasswordDialog::~KexiDBPasswordDialog() { } void KexiDBPasswordDialog::done(int r) { if (r == TQDialog::Accepted) { m_cdata->password = TQString::fromLatin1(password()); } // if (d->showConnectionDetailsExecuted || ret == TQDialog::Accepted) { /* } else { m_action = Exit; return true; } }*/ KPasswordDialog::done(r); } void KexiDBPasswordDialog::slotShowConnectionDetails() { m_showConnectionDetailsRequested = true; close(); } //--------------------------------- KexiStartupHandler::KexiStartupHandler() : TQObject(0,"KexiStartupHandler") , KexiStartupData() , d( new KexiStartupHandlerPrivate() ) { } KexiStartupHandler::~KexiStartupHandler() { delete d; } bool KexiStartupHandler::getAutoopenObjects(TDECmdLineArgs *args, const TQCString &action_name) { QCStringList list = args->getOptionList(action_name); QCStringList::ConstIterator it; bool atLeastOneFound = false; for ( it = list.constBegin(); it!=list.constEnd(); ++it) { TQString type_name, obj_name, item=*it; int idx; bool name_required = true; if (action_name=="new") { obj_name = ""; stripQuotes(item, type_name); name_required = false; } else {//open, design, text... TQString defaultType; if (action_name=="execute") defaultType = "macro"; else defaultType = "table"; //option with " " (set default type) if (stripQuotes(item, obj_name)) { type_name = defaultType; } else if ((idx = item.find(':'))!=-1) { //option with type name specified: type_name = item.left(idx).lower(); obj_name = item.mid(idx+1); //optional: remove "" if (obj_name.left(1)=="\"" && obj_name.right(1)=="\"") obj_name = obj_name.mid(1, obj_name.length()-2); } else { //just obj. name: set default type name obj_name = item; type_name = defaultType; } } if (type_name.isEmpty()) continue; if (name_required && obj_name.isEmpty()) continue; KexiProjectData::ObjectInfo info; info["name"]=obj_name; info["type"]=type_name; info["action"]=action_name; //ok, now add info for this object atLeastOneFound = true; if (projectData()) projectData()->autoopenObjects.append( info ); else return true; //no need to find more because we do not have projectData() anyway } //for return atLeastOneFound; } tristate KexiStartupHandler::init(int /*argc*/, char ** /*argv*/) { m_action = DoNothing; // d->showConnectionDetailsExecuted = false; TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(0); if (!args) return true; KexiDB::ConnectionData cdata; const TQString connectionShortcutFileName( args->getOption("connection") ); if (!connectionShortcutFileName.isEmpty()) { KexiDBConnShortcutFile connectionShortcut( connectionShortcutFileName ); if (!connectionShortcut.loadConnectionData(cdata)) { //! @todo Show error message from KexiDBConnShortcutFile when there's one implemented. //! For we're displaying generic error msg. KMessageBox::sorry( 0, "" +i18n("Could not read connection information from connection shortcut " "file \"%1\".

Check whether the file has valid contents.") .arg(TQDir::convertSeparators(connectionShortcut.fileName()))); return false; } } if (!args->getOption("dbdriver").isEmpty()) cdata.driverName = args->getOption("dbdriver"); TQString fileType( args->getOption("type").lower() ); if (args->count()>0 && (!fileType.isEmpty() && fileType!="project" && fileType!="shortcut" && fileType!="connection")) { KMessageBox::sorry( 0, i18n("You have specified invalid argument (\"%1\") for \"type\" command-line option.") .arg(fileType)); return false; } // if (cdata.driverName.isEmpty()) // cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName(); if (!args->getOption("host").isEmpty()) cdata.hostName = args->getOption("host"); if (!args->getOption("local-socket").isEmpty()) cdata.localSocketFileName = args->getOption("local-socket"); if (!args->getOption("user").isEmpty()) cdata.userName = args->getOption("user"); // cdata.password = args->getOption("password"); bool fileDriverSelected; if (cdata.driverName.isEmpty()) fileDriverSelected = true; else { KexiDB::DriverManager dm; KexiDB::Driver::Info dinfo = dm.driverInfo(cdata.driverName); if (dinfo.name.isEmpty()) { //driver name provided explicitly, but not found KMessageBox::sorry(0, dm.errorMsg()); return false; } fileDriverSelected = dinfo.fileBased; } bool projectFileExists = false; //obfuscate the password, if present //removed /* for (int i=1; i<(argc-1); i++) { if (qstrcmp("--password",argv[i])==0 || qstrcmp("-password",argv[i])==0) { TQCString pwd(argv[i+1]); if (!pwd.isEmpty()) { pwd.fill(' '); pwd[0]='x'; qstrcpy(argv[i+1], (const char*)pwd); } break; } } */ const TQString portStr = args->getOption("port"); if (!portStr.isEmpty()) { bool ok; const int p = portStr.toInt(&ok); if (ok && p > 0) cdata.port = p; else { KMessageBox::sorry( 0, i18n("You have specified invalid port number \"%1\".")); return false; } } m_forcedUserMode = args->isSet("user-mode"); m_forcedDesignMode = args->isSet("design-mode"); m_isProjectNavigatorVisible = args->isSet("show-navigator"); bool createDB = args->isSet("createdb"); const bool alsoOpenDB = args->isSet("create-opendb"); if (alsoOpenDB) createDB = true; const bool dropDB = args->isSet("dropdb"); const bool openExisting = !createDB && !dropDB; const bool readOnly = args->isSet("readonly"); const TQString couldnotMsg = TQString::fromLatin1("\n") +i18n("Could not start Kexi application this way."); if (createDB && dropDB) { KMessageBox::sorry( 0, i18n( "You have used both \"createdb\" and \"dropdb\" startup options.")+couldnotMsg); return false; }; if (createDB || dropDB) { if (args->count()<1) { KMessageBox::sorry( 0, i18n("No project name specified.") ); return false; } m_action = Exit; } //TODO: add option for non-gui; integrate with KWallet; // move to static KexiProject method if (!fileDriverSelected && !cdata.driverName.isEmpty() && cdata.password.isEmpty()) { if (cdata.password.isEmpty()) { delete d->passwordDialog; d->passwordDialog = new KexiDBPasswordDialog(0, cdata, true); // connect( d->passwordDialog, TQT_SIGNAL(user1Clicked()), // this, TQT_SLOT(slotShowConnectionDetails()) ); const int ret = d->passwordDialog->exec(); if (d->passwordDialog->showConnectionDetailsRequested() || ret == TQDialog::Accepted) { // if ( ret == TQDialog::Accepted ) { // if (TQDialog::Accepted == KPasswordDialog::getPassword(pwd, msg)) { //moved cdata.password = TQString(pwd); // } } else { m_action = Exit; return true; } } } /* kdDebug() << "ARGC==" << args->count() << endl; for (int i=0;icount();i++) { kdDebug() << "ARG" <count()>=1) { TQString prjName; TQString fileName; if (fileDriverSelected) { fileName = TQFile::decodeName(args->arg(0)); } else { prjName = TQString::fromLocal8Bit(args->arg(0)); } if (fileDriverSelected) { TQFileInfo finfo(fileName); prjName = finfo.fileName(); //filename only, to avoid messy names like when Kexi is started with "../../db" arg cdata.setFileName( finfo.absFilePath() ); projectFileExists = finfo.exists(); if (dropDB && !projectFileExists) { KMessageBox::sorry(0, i18n("Could not remove project.\nThe file \"%1\" does not exist.") .arg(TQDir::convertSeparators(cdata.dbFileName()))); return 0; } } if (createDB) { if (cdata.driverName.isEmpty()) cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName(); m_projectData = new KexiProjectData(cdata, prjName); //dummy } else { if (fileDriverSelected) { int detectOptions = 0; if (fileType=="project") detectOptions |= ThisIsAProjectFile; else if (fileType=="shortcut") detectOptions |= ThisIsAShortcutToAProjectFile; else if (fileType=="connection") detectOptions |= ThisIsAShortcutToAConnectionData; if (dropDB) detectOptions |= DontConvert; TQString detectedDriverName; const tristate res = detectActionForFile( m_importActionData, detectedDriverName, cdata.driverName, cdata.fileName(), 0, detectOptions ); if (true != res) return res; if (m_importActionData) { //importing action m_action = ImportProject; return true; } //opening action cdata.driverName = detectedDriverName; if (cdata.driverName=="shortcut") { //get information for a shortcut file d->shortcutFile = new KexiDBShortcutFile(cdata.fileName()); m_projectData = new KexiProjectData(); if (!d->shortcutFile->loadProjectData(*m_projectData, &d->shortcutFileGroupKey)) { KMessageBox::sorry(0, i18n("Could not open shortcut file\n\"%1\".") .arg(TQDir::convertSeparators(cdata.fileName()))); delete m_projectData; m_projectData = 0; delete d->shortcutFile; d->shortcutFile = 0; return false; } d->connDialog = new KexiDBConnectionDialog( *m_projectData, d->shortcutFile->fileName()); connect(d->connDialog, TQT_SIGNAL(saveChanges()), this, TQT_SLOT(slotSaveShortcutFileChanges())); int res = d->connDialog->exec(); if (res == TQDialog::Accepted) { //get (possibly changed) prj data *m_projectData = d->connDialog->currentProjectData(); } delete d->connDialog; d->connDialog = 0; delete d->shortcutFile; d->shortcutFile = 0; if (res == TQDialog::Rejected) { delete m_projectData; m_projectData = 0; return cancelled; } } else if (cdata.driverName=="connection") { //get information for a connection file d->connShortcutFile = new KexiDBConnShortcutFile(cdata.fileName()); if (!d->connShortcutFile->loadConnectionData(cdata, &d->shortcutFileGroupKey)) { KMessageBox::sorry(0, i18n("Could not open connection data file\n\"%1\".") .arg(TQDir::convertSeparators(cdata.fileName()))); delete d->connShortcutFile; d->connShortcutFile = 0; return false; } bool cancel = false; const bool showConnectionDialog = !args->isSet("skip-conn-dialog"); while (true) { if (showConnectionDialog) { //show connection dialog, so user can change parameters if (!d->connDialog) { d->connDialog = new KexiDBConnectionDialog( cdata, d->connShortcutFile->fileName()); connect(d->connDialog, TQT_SIGNAL(saveChanges()), this, TQT_SLOT(slotSaveShortcutFileChanges())); } const int res = d->connDialog->exec(); if (res == TQDialog::Accepted) { //get (possibly changed) prj data cdata = *d->connDialog->currentProjectData().constConnectionData(); } else { cancel = true; break; } } m_projectData = selectProject(&cdata, cancel); if (m_projectData || cancel || !showConnectionDialog) break; } delete d->connShortcutFile; d->connShortcutFile = 0; delete d->connDialog; d->connDialog = 0; if (cancel) return cancelled; } else m_projectData = new KexiProjectData(cdata, prjName); } else m_projectData = new KexiProjectData(cdata, prjName); } // if (!m_projectData) // return false; } if (args->count()>1) { //TODO: KRun another Kexi instances } //let's show connection details, user asked for that in the "password dialog" if (d->passwordDialog && d->passwordDialog->showConnectionDetailsRequested()) { d->connDialog = new KexiDBConnectionDialog(*m_projectData); // connect(d->connDialog->tabWidget->mainWidget, TQT_SIGNAL(saveChanges()), // this, TQT_SLOT(slotSaveShortcutFileChanges())); int res = d->connDialog->exec(); if (res == TQDialog::Accepted) { //get (possibly changed) prj data *m_projectData = d->connDialog->currentProjectData(); } delete d->connDialog; d->connDialog = 0; if (res == TQDialog::Rejected) { delete m_projectData; m_projectData = 0; return cancelled; } } //---autoopen objects: const bool atLeastOneAOOFound = getAutoopenObjects(args, "open") || getAutoopenObjects(args, "design") || getAutoopenObjects(args, "edittext") || getAutoopenObjects(args, "execute") || getAutoopenObjects(args, "new") || getAutoopenObjects(args, "print") || getAutoopenObjects(args, "print-preview"); if (atLeastOneAOOFound && !openExisting) { KMessageBox::information( 0, i18n("You have specified a few database objects to be opened automatically, " "using startup options.\n" "These options will be ignored because it is not available while creating " "or dropping projects.")); } if (createDB) { bool creationNancelled; KexiGUIMessageHandler gui; KexiProject *prj = KexiProject::createBlankProject(creationNancelled, projectData(), &gui); bool ok = prj!=0; delete prj; if (creationNancelled) return cancelled; if (!alsoOpenDB) { if (ok) { KMessageBox::information( 0, i18n("Project \"%1\" created successfully.") .arg( TQDir::convertSeparators(projectData()->databaseName()) )); } return ok; } } else if (dropDB) { KexiGUIMessageHandler gui; tristate res = KexiProject::dropProject(projectData(), &gui, false/*ask*/); if (res==true) KMessageBox::information( 0, i18n("Project \"%1\" dropped successfully.") .arg( TQDir::convertSeparators(projectData()->databaseName()) )); return res!=false; } //------ /* if (m_forcedFinalMode || (m_projectData && projectData->finalMode())) { //TODO: maybe also auto allow to open objects... KexiMainWindowImpl::initFinal(m_projectData); return; }*/ if (!m_projectData) { cdata = KexiDB::ConnectionData(); //clear if (args->isSet("skip-startup-dialog") || !KexiStartupDialog::shouldBeShown()) return true; if (!d->startupDialog) { //create d->startupDialog for reuse because it can be used again after conn err. d->startupDialog = new KexiStartupDialog( KexiStartupDialog::Everything, KexiStartupDialog::CheckBoxDoNotShowAgain, Kexi::connset(), Kexi::recentProjects(), 0, "KexiStartupDialog"); } if (d->startupDialog->exec()!=TQDialog::Accepted) return true; const int r = d->startupDialog->result(); if (r == KexiStartupDialog::CreateBlankResult) { m_action = CreateBlankProject; return true; } else if (r == KexiStartupDialog::ImportResult) { m_action = ImportProject; return true; } else if (r == KexiStartupDialog::CreateFromTemplateResult) { const TQString selFile( d->startupDialog->selectedFileName() ); cdata.setFileName( selFile ); TQString detectedDriverName; const tristate res = detectActionForFile( m_importActionData, detectedDriverName, cdata.driverName, selFile ); if (true != res) return res; if (m_importActionData || detectedDriverName.isEmpty()) return false; cdata.driverName = detectedDriverName; m_projectData = new KexiProjectData(cdata, selFile); m_projectData->autoopenObjects = d->startupDialog->autoopenObjects(); m_action = CreateFromTemplate; return true; } else if (r == KexiStartupDialog::OpenExistingResult) { // kdDebug() << "Existing project --------" << endl; const TQString selFile( d->startupDialog->selectedFileName() ); if (!selFile.isEmpty()) { //file-based project // kdDebug() << "Project File: " << selFile << endl; cdata.setFileName( selFile ); TQString detectedDriverName; const tristate res = detectActionForFile( m_importActionData, detectedDriverName, cdata.driverName, selFile ); if (true != res) return res; if (m_importActionData) { //importing action m_action = ImportProject; return true; } if (detectedDriverName.isEmpty()) return false; cdata.driverName = detectedDriverName; m_projectData = new KexiProjectData(cdata, selFile); } else if (d->startupDialog->selectedExistingConnection()) { // kdDebug() << "Existing connection: " << // d->startupDialog->selectedExistingConnection()->serverInfoString() << endl; KexiDB::ConnectionData *cdata = d->startupDialog->selectedExistingConnection(); //ok, now we will try to show projects for this connection to the user bool cancelled; m_projectData = selectProject( cdata, cancelled ); if (!m_projectData && !cancelled || cancelled) { //try again return init(0, 0); } //not needed anymore delete d->startupDialog; d->startupDialog = 0; } } else if (r==KexiStartupDialog::OpenRecentResult) { // kdDebug() << "Recent project --------" << endl; const KexiProjectData *data = d->startupDialog->selectedProjectData(); if (data) { // kdDebug() << "Selected project: database=" << data->databaseName() // << " connection=" << data->constConnectionData()->serverInfoString() << endl; } //! @todo return data!=0; } if (!m_projectData) return true; } if (m_projectData && (openExisting || (createDB && alsoOpenDB))) { m_projectData->setReadOnly( readOnly ); m_action = OpenProject; } //show if wasn't show yet // importantInfo(true); return true; } tristate KexiStartupHandler::detectActionForFile( KexiStartupData::Import& detectedImportAction, TQString& detectedDriverName, const TQString& _suggestedDriverName, const TQString &dbFileName, TQWidget *parent, int options ) { detectedImportAction = KexiStartupData::Import(); //clear TQString suggestedDriverName(_suggestedDriverName); //safe detectedDriverName = TQString(); TQFileInfo finfo(dbFileName); if (dbFileName.isEmpty() || !finfo.isReadable()) { if (!(options & SkipMessages)) KMessageBox::sorry(parent, i18n("

Could not open project.

") +i18n("

The file \"%1\" does not exist or is not readable.

") .arg(TQDir::convertSeparators(dbFileName)) +i18n("Check the file's permissions and whether it is already opened " "and locked by another application.")); return false; } KMimeType::Ptr ptr; TQString mimename; const bool thisIsShortcut = (options & ThisIsAShortcutToAProjectFile) || (options & ThisIsAShortcutToAConnectionData); if ((options & ThisIsAProjectFile) || !thisIsShortcut) { //try this detection if "project file" mode is forced or no type is forced: ptr = KMimeType::findByFileContent(dbFileName); mimename = ptr.data()->name(); kdDebug() << "KexiStartupHandler::detectActionForFile(): found mime is: " << mimename << endl; if (mimename.isEmpty() || mimename=="application/octet-stream" || mimename=="text/plain") { //try by URL: ptr = KMimeType::findByURL(dbFileName); mimename = ptr.data()->name(); } } if (mimename.isEmpty() || mimename=="application/octet-stream") { // perhaps the file is locked TQFile f(dbFileName); if (!f.open(IO_ReadOnly)) { // BTW: similar error msg is provided in SQLiteConnection::drv_useDatabase() if (!(options & SkipMessages)) KMessageBox::sorry(parent, i18n("

Could not open project.

") +i18n("

The file \"%1\" is not readable.

") .arg(TQDir::convertSeparators(dbFileName)) +i18n("Check the file's permissions and whether it is already opened " "and locked by another application.")); return false; } } if ((options & ThisIsAShortcutToAProjectFile) || mimename=="application/x-kexiproject-shortcut") { detectedDriverName = "shortcut"; return true; } if ((options & ThisIsAShortcutToAConnectionData) || mimename=="application/x-kexi-connectiondata") { detectedDriverName = "connection"; return true; } //! @todo rather check this using migration drivers' //! X-KexiSupportedMimeTypes [strlist] property if (ptr.data()) { if (mimename=="application/x-msaccess") { if ((options & SkipMessages) || KMessageBox::Yes != KMessageBox::questionYesNo( parent, i18n("\"%1\" is an external file of type:\n\"%2\".\n" "Do you want to import the file as a Kexi project?") .arg(TQDir::convertSeparators(dbFileName)).arg(ptr.data()->comment()), i18n("Open External File"), KGuiItem(i18n("Import...")), KStdGuiItem::cancel() ) ) { return cancelled; } detectedImportAction.mimeType = mimename; detectedImportAction.fileName = dbFileName; return true; } } if (!finfo.isWritable()) { //! @todo if file is ro: change project mode (but do not care if we're jsut importing) } // "application/x-kexiproject-sqlite", etc.: TQString tmpDriverName = Kexi::driverManager().lookupByMime(mimename).latin1(); //@todo What about trying to reuse KOFFICE FILTER CHAINS here? bool useDetectedDriver = suggestedDriverName.isEmpty() || suggestedDriverName.lower()==detectedDriverName.lower(); if (!useDetectedDriver) { int res = KMessageBox::Yes; if (!(options & SkipMessages)) res = KMessageBox::warningYesNoCancel(parent, i18n( "The project file \"%1\" is recognized as compatible with \"%2\" database driver, " "while you have asked for \"%3\" database driver to be used.\n" "Do you want to use \"%4\" database driver?") .arg(TQDir::convertSeparators(dbFileName)) .arg(tmpDriverName).arg(suggestedDriverName).arg(tmpDriverName)); if (KMessageBox::Yes == res) useDetectedDriver = true; else if (KMessageBox::Cancel == res) return cancelled; } if (useDetectedDriver) { detectedDriverName = tmpDriverName; } else {//use suggested driver detectedDriverName = suggestedDriverName; } // kdDebug() << "KexiStartupHandler::detectActionForFile(): driver name: " << detectedDriverName << endl; //hardcoded for convenience: const TQString newFileFormat = "SQLite3"; if (!(options & DontConvert || options & SkipMessages) && detectedDriverName.lower()=="sqlite2" && detectedDriverName.lower()!=suggestedDriverName.lower() && KMessageBox::Yes == KMessageBox::questionYesNo(parent, i18n( "Previous version of database file format (\"%1\") is detected in the \"%2\" " "project file.\nDo you want to convert the project to a new \"%3\" format (recommended)?") .arg(detectedDriverName).arg(TQDir::convertSeparators(dbFileName)).arg(newFileFormat)) ) { // SQLite2ToSQLite3Migration *migr = new SQLite2ToSQLite3Migration migr( finfo.absFilePath() ); tristate res = migr.run(); // kdDebug() << "--- migr.run() END ---" <")+i18n("Possible problems:")); possibleProblemsInfoMsg += TQString::fromLatin1("

"); } if (!(options & SkipMessages)) KMessageBox::detailedSorry(parent, i18n( "The file \"%1\" is not recognized as being supported by Kexi.") .arg(TQDir::convertSeparators(dbFileName)), TQString::fromLatin1("

") +i18n("Database driver for this file type not found.\nDetected MIME type: %1") .arg(mimename) +(ptr.data()->comment().isEmpty() ? TQString::fromLatin1(".") : TQString::fromLatin1(" (%1).").arg(ptr.data()->comment())) +TQString::fromLatin1("

") +possibleProblemsInfoMsg); return false; } return true; } KexiProjectData* KexiStartupHandler::selectProject(KexiDB::ConnectionData *cdata, bool& cancelled, TQWidget *parent) { clearStatus(); cancelled = false; if (!cdata) return 0; if (!cdata->savePassword && cdata->password.isEmpty()) { if (!d->passwordDialog) d->passwordDialog = new KexiDBPasswordDialog(0, *cdata, false); const int ret = d->passwordDialog->exec(); if (d->passwordDialog->showConnectionDetailsRequested() || ret == TQDialog::Accepted) { } else { cancelled = true; return 0; } } KexiProjectData* projectData = 0; //dialog for selecting a project KexiProjectSelectorDialog prjdlg( parent, "prjdlg", cdata, true, false ); if (!prjdlg.projectSet() || prjdlg.projectSet()->error()) { KexiGUIMessageHandler msgh; if (prjdlg.projectSet()) msgh.showErrorMessage(prjdlg.projectSet(), i18n("Could not load list of available projects for %1 database server.") .arg(cdata->serverInfoString(true))); else msgh.showErrorMessage( i18n("Could not load list of available projects for %1 database server.") .arg(cdata->serverInfoString(true))); // setStatus(i18n("Could not load list of available projects for database server \"%1\"") // .arg(cdata->serverInfoString(true)), prjdlg.projectSet()->errorMsg()); return 0; } if (prjdlg.exec()!=TQDialog::Accepted) { cancelled = true; return 0; } if (prjdlg.selectedProjectData()) { //deep copy projectData = new KexiProjectData(*prjdlg.selectedProjectData()); } return projectData; } void KexiStartupHandler::slotSaveShortcutFileChanges() { bool ok = true; if (d->shortcutFile) ok = d->shortcutFile->saveProjectData(d->connDialog->currentProjectData(), d->connDialog->savePasswordOptionSelected(), &d->shortcutFileGroupKey ); else if (d->connShortcutFile) ok = d->connShortcutFile->saveConnectionData( *d->connDialog->currentProjectData().connectionData(), d->connDialog->savePasswordOptionSelected(), &d->shortcutFileGroupKey ); if (!ok) { KMessageBox::sorry(0, i18n("Failed saving connection data to\n\"%1\" file.") .arg(TQDir::convertSeparators(d->shortcutFile->fileName()))); } } /*void KexiStartupHandler::slotShowConnectionDetails() { d->passwordDialog->close(); d->showConnectionDetailsExecuted = true; }*/ #include "KexiStartup.moc"