00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KexiStartup.h"
00021 #ifdef Q_WS_WIN
00022 # include "KexiStartup_p_win.h"
00023 #else
00024 # include "KexiStartup_p.h"
00025 #endif
00026
00027 #include "kexiproject.h"
00028 #include "kexiprojectdata.h"
00029 #include "kexiprojectset.h"
00030 #include "kexiguimsghandler.h"
00031
00032 #include <kexidb/driver.h>
00033 #include <kexidb/drivermanager.h>
00034 #include "KexiStartupDialog.h"
00035 #include "KexiConnSelector.h"
00036 #include "KexiProjectSelectorBase.h"
00037 #include "KexiProjectSelector.h"
00038 #include "KexiNewProjectWizard.h"
00039 #include <kexidbconnectionwidget.h>
00040 #include <kexidbshortcutfile.h>
00041
00042 #include <kdebug.h>
00043 #include <klocale.h>
00044 #include <kmimetype.h>
00045 #include <kmessagebox.h>
00046 #include <kcmdlineargs.h>
00047 #include <kdeversion.h>
00048 #include <kprogress.h>
00049 #include <ktextedit.h>
00050 #include <kstaticdeleter.h>
00051
00052 #include <unistd.h>
00053
00054 #if KDE_IS_VERSION(3,1,9)
00055 # include <kuser.h>
00056 #endif
00057
00058 #include <qcstring.h>
00059 #include <qapplication.h>
00060 #include <qlayout.h>
00061
00062 namespace Kexi {
00063 static KStaticDeleter<KexiStartupHandler> Kexi_startupHandlerDeleter;
00064 KexiStartupHandler* _startupHandler = 0;
00065
00066 KexiStartupHandler& startupHandler()
00067 {
00068 if (!_startupHandler)
00069 Kexi_startupHandlerDeleter.setObject( _startupHandler, new KexiStartupHandler() );
00070 return *_startupHandler;
00071 }
00072 }
00073
00074
00075
00077 class KexiStartupHandlerPrivate
00078 {
00079 public:
00080 KexiStartupHandlerPrivate()
00081 : passwordDialog(0)
00082 , shortcutFile(0), connShortcutFile(0), connDialog(0), startupDialog(0)
00083 {
00084 }
00085
00086 ~KexiStartupHandlerPrivate()
00087 {
00088 delete passwordDialog;
00089 delete connDialog;
00090 delete startupDialog;
00091 }
00092
00093 KexiDBPasswordDialog* passwordDialog;
00094
00095 KexiDBShortcutFile *shortcutFile;
00096 KexiDBConnShortcutFile *connShortcutFile;
00097 KexiDBConnectionDialog *connDialog;
00098 QString shortcutFileGroupKey;
00099 KexiStartupDialog *startupDialog;
00100 };
00101
00102
00103
00104 static bool stripQuotes(const QString &item, QString &name)
00105 {
00106 if (item.left(1)=="\"" && item.right(1)=="\"") {
00107 name = item.mid(1, item.length()-2);
00108 return true;
00109 }
00110 name = item;
00111 return false;
00112 }
00113
00114 void updateProgressBar(KProgressDialog *pd, char *buffer, int buflen)
00115 {
00116 char *p = buffer;
00117 QCString line(80);
00118 for (int i=0; i<buflen; i++, p++) {
00119 if ((i==0 || buffer[i-1]=='\n') && buffer[i]=='%') {
00120 bool ok;
00121 int j=0;
00122
00123 ++i;
00124 line="";
00125 for (;i<buflen && *p>='0' && *p<='9'; j++, i++, p++)
00126 line+=QChar(*p);
00127 --i; --p;
00128 int percent = line.toInt(&ok);
00129 if (ok && percent>=0 && percent<=100 && pd->progressBar()->progress()<percent) {
00130
00131 pd->progressBar()->setProgress(percent);
00132 qApp->processEvents(100);
00133 }
00134 }
00135 }
00136 }
00137
00138
00139
00140 KexiDBPasswordDialog::KexiDBPasswordDialog(QWidget *parent, KexiDB::ConnectionData& cdata, bool showDetailsButton)
00141 : KPasswordDialog( KPasswordDialog::Password, false,
00142 showDetailsButton ? (int)KDialogBase::User1 : 0, parent )
00143 , m_cdata(&cdata)
00144 , m_showConnectionDetailsRequested(false)
00145 {
00146 QString msg = "<H2>" + i18n("Opening database") + "</H2><p>"
00147 + i18n("Please enter the password.") + "</p>";
00148
00149
00150
00151
00152 QString srv = cdata.serverInfoString(false);
00153 if (srv.isEmpty() || srv.lower()=="localhost")
00154 srv = i18n("local database server");
00155
00156 msg += ("</p><p>"+i18n("Database server: %1").arg(QString("<nobr>")+srv+"</nobr>")+"</p>");
00157
00158 QString usr;
00159 if (cdata.userName.isEmpty())
00160 usr = i18n("unspecified user", "(unspecified)");
00161 else
00162 usr = cdata.userName;
00163
00164 msg += ("<p>"+i18n("Username: %1").arg(usr)+"</p>");
00165
00166 setPrompt( msg );
00167 if (showDetailsButton) {
00168 connect( this, SIGNAL(user1Clicked()),
00169 this, SLOT(slotShowConnectionDetails()) );
00170 setButtonText(KDialogBase::User1, i18n("&Details")+ " >>");
00171 }
00172 setButtonOK(KGuiItem(i18n("&Open"), "fileopen"));
00173 }
00174
00175 KexiDBPasswordDialog::~KexiDBPasswordDialog()
00176 {
00177 }
00178
00179 void KexiDBPasswordDialog::done(int r)
00180 {
00181 if (r == QDialog::Accepted) {
00182 m_cdata->password = QString::fromLatin1(password());
00183 }
00184
00185
00186
00187
00188
00189
00190 KPasswordDialog::done(r);
00191 }
00192
00193 void KexiDBPasswordDialog::slotShowConnectionDetails()
00194 {
00195 m_showConnectionDetailsRequested = true;
00196 close();
00197 }
00198
00199
00200 KexiStartupHandler::KexiStartupHandler()
00201 : QObject(0,"KexiStartupHandler")
00202 , KexiStartupData()
00203 , d( new KexiStartupHandlerPrivate() )
00204 {
00205 }
00206
00207 KexiStartupHandler::~KexiStartupHandler()
00208 {
00209 delete d;
00210 }
00211
00212 bool KexiStartupHandler::getAutoopenObjects(KCmdLineArgs *args, const QCString &action_name)
00213 {
00214 QCStringList list = args->getOptionList(action_name);
00215 QCStringList::ConstIterator it;
00216 bool atLeastOneFound = false;
00217 for ( it = list.constBegin(); it!=list.constEnd(); ++it) {
00218 QString type_name, obj_name, item=*it;
00219 int idx;
00220 bool name_required = true;
00221 if (action_name=="new") {
00222 obj_name = "";
00223 stripQuotes(item, type_name);
00224 name_required = false;
00225 }
00226 else {
00227
00228 if (stripQuotes(item, obj_name)) {
00229 type_name = "table";
00230 }
00231 else if ((idx = item.find(':'))!=-1) {
00232
00233 type_name = item.left(idx).lower();
00234 obj_name = item.mid(idx+1);
00235
00236 if (obj_name.left(1)=="\"" && obj_name.right(1)=="\"")
00237 obj_name = obj_name.mid(1, obj_name.length()-2);
00238 }
00239 else {
00240
00241 obj_name = item;
00242 type_name = "table";
00243 }
00244 }
00245 if (type_name.isEmpty())
00246 continue;
00247 if (name_required && obj_name.isEmpty())
00248 continue;
00249
00250 KexiProjectData::ObjectInfo info;
00251 info["name"]=obj_name;
00252 info["type"]=type_name;
00253 info["action"]=action_name;
00254
00255 atLeastOneFound = true;
00256 if (projectData())
00257 projectData()->autoopenObjects.append( info );
00258 else
00259 return true;
00260 }
00261 return atLeastOneFound;
00262 }
00263
00264 tristate KexiStartupHandler::init(int , char ** )
00265 {
00266 m_action = DoNothing;
00267
00268 KCmdLineArgs *args = KCmdLineArgs::parsedArgs(0);
00269 if (!args)
00270 return true;
00271
00272 KexiDB::ConnectionData cdata;
00273
00274 const QString connectionShortcutFileName( args->getOption("connection") );
00275 if (!connectionShortcutFileName.isEmpty()) {
00276 KexiDBConnShortcutFile connectionShortcut( connectionShortcutFileName );
00277 if (!connectionShortcut.loadConnectionData(cdata)) {
00280 KMessageBox::sorry( 0, "<qt>"
00281 +i18n("Could not read connection information from connection shortcut "
00282 "file <nobr>\"%1\"</nobr>.<br><br>Check whether the file has valid contents.")
00283 .arg(QDir::convertSeparators(connectionShortcut.fileName())));
00284 return false;
00285 }
00286 }
00287
00288 if (!args->getOption("dbdriver").isEmpty())
00289 cdata.driverName = args->getOption("dbdriver");
00290
00291 QString fileType( args->getOption("type").lower() );
00292 if (args->count()>0 && (!fileType.isEmpty() && fileType!="project" && fileType!="shortcut" && fileType!="connection")) {
00293 KMessageBox::sorry( 0,
00294 i18n("You have specified invalid argument (\"%1\") for \"type\" command-line option.")
00295 .arg(fileType));
00296 return false;
00297 }
00298
00299
00300
00301 #ifdef KEXI_SERVER_SUPPORT
00302 if (!args->getOption("host").isEmpty())
00303 cdata.hostName = args->getOption("host");
00304 if (!args->getOption("local-socket").isEmpty())
00305 cdata.localSocketFileName = args->getOption("local-socket");
00306 if (!args->getOption("user").isEmpty())
00307 cdata.userName = args->getOption("user");
00308 #endif
00309
00310 bool fileDriverSelected;
00311 if (cdata.driverName.isEmpty())
00312 fileDriverSelected = true;
00313 else {
00314 KexiDB::DriverManager dm;
00315 KexiDB::Driver::Info dinfo = dm.driverInfo(cdata.driverName);
00316 if (dinfo.name.isEmpty()) {
00317
00318 KMessageBox::sorry(0, dm.errorMsg());
00319 return false;
00320 }
00321 fileDriverSelected = dinfo.fileBased;
00322 }
00323 bool projectFileExists = false;
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 #ifdef KEXI_SERVER_SUPPORT
00344 const QString portStr = args->getOption("port");
00345 if (!portStr.isEmpty()) {
00346 bool ok;
00347 const int p = portStr.toInt(&ok);
00348 if (ok && p > 0)
00349 cdata.port = p;
00350 else {
00351 KMessageBox::sorry( 0,
00352 i18n("You have specified invalid port number \"%1\"."));
00353 return false;
00354 }
00355 }
00356 #endif
00357
00358 #ifdef KEXI_SHOW_UNIMPLEMENTED
00359 m_forcedFinalMode = args->isSet("final-mode");
00360 m_forcedDesignMode = args->isSet("design-mode");
00361 #else
00362 m_forcedFinalMode = false;
00363 m_forcedDesignMode = false;
00364 #endif
00365 bool createDB = args->isSet("createdb");
00366 const bool alsoOpenDB = args->isSet("create-opendb");
00367 if (alsoOpenDB)
00368 createDB = true;
00369 const bool dropDB = args->isSet("dropdb");
00370 const bool openExisting = !createDB && !dropDB;
00371 const QString couldnotMsg = QString::fromLatin1("\n")
00372 +i18n("Could not start Kexi application this way.");
00373
00374 if (createDB && dropDB) {
00375 KMessageBox::sorry( 0, i18n(
00376 "You have used both \"createdb\" and \"dropdb\" startup options.")+couldnotMsg);
00377 return false;
00378 };
00379
00380 if (createDB || dropDB) {
00381 if (args->count()<1) {
00382 KMessageBox::sorry( 0, i18n("No project name specified.") );
00383 return false;
00384 }
00385 m_action = Exit;
00386 }
00387
00388
00389
00390 if (!fileDriverSelected && !cdata.driverName.isEmpty() && cdata.password.isEmpty()) {
00391
00392 if (cdata.password.isEmpty()) {
00393 delete d->passwordDialog;
00394 d->passwordDialog = new KexiDBPasswordDialog(0, cdata, true);
00395
00396
00397 const int ret = d->passwordDialog->exec();
00398 if (d->passwordDialog->showConnectionDetailsRequested() || ret == QDialog::Accepted) {
00399
00400
00401
00402
00403 } else {
00404 m_action = Exit;
00405 return true;
00406 }
00407 }
00408 }
00409
00410
00411
00412
00413
00414
00415 if (m_forcedFinalMode && m_forcedDesignMode) {
00416 KMessageBox::sorry( 0, i18n(
00417 "You have used both \"final-mode\" and \"design-mode\" startup options.")+couldnotMsg);
00418 return false;
00419 }
00420
00421
00422 if (args->count()>=1) {
00423 QString prjName;
00424 if (fileDriverSelected)
00425 prjName = QFile::decodeName(args->arg(0));
00426 else
00427 prjName = QString::fromLocal8Bit(args->arg(0));
00428
00429 if (fileDriverSelected) {
00430 QFileInfo finfo(prjName);
00431 cdata.setFileName( finfo.absFilePath() );
00432 projectFileExists = finfo.exists();
00433
00434 if (dropDB && !projectFileExists) {
00435 KMessageBox::sorry(0,
00436 i18n("Could not remove project.\nThe file \"%1\" does not exist.")
00437 .arg(QDir::convertSeparators(cdata.dbFileName())));
00438 return 0;
00439 }
00440 }
00441
00442 if (createDB) {
00443 if (cdata.driverName.isEmpty())
00444 cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName();
00445 m_projectData = new KexiProjectData(cdata, prjName);
00446 }
00447 else {
00448 if (fileDriverSelected) {
00449 int detectOptions = 0;
00450 if (fileType=="project")
00451 detectOptions |= ThisIsAProjectFile;
00452 else if (fileType=="shortcut")
00453 detectOptions |= ThisIsAShortcutToAProjectFile;
00454 else if (fileType=="connection")
00455 detectOptions |= ThisIsAShortcutToAConnectionData;
00456
00457 if (dropDB)
00458 detectOptions |= DontConvert;
00459
00460 QString detectedDriverName;
00461 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00462 cdata.driverName, cdata.fileName(), 0, detectOptions );
00463 if (true != res)
00464 return res;
00465
00466 if (m_importActionData) {
00467 m_action = ImportProject;
00468 return true;
00469 }
00470
00471
00472 cdata.driverName = detectedDriverName;
00473 if (cdata.driverName=="shortcut") {
00474
00475 d->shortcutFile = new KexiDBShortcutFile(cdata.fileName());
00476 m_projectData = new KexiProjectData();
00477 if (!d->shortcutFile->loadProjectData(*m_projectData, &d->shortcutFileGroupKey)) {
00478 KMessageBox::sorry(0, i18n("Could not open shortcut file\n\"%1\".")
00479 .arg(QDir::convertSeparators(cdata.fileName())));
00480 delete m_projectData;
00481 m_projectData = 0;
00482 delete d->shortcutFile;
00483 d->shortcutFile = 0;
00484 return false;
00485 }
00486 d->connDialog = new KexiDBConnectionDialog(
00487 *m_projectData, d->shortcutFile->fileName());
00488 connect(d->connDialog, SIGNAL(saveChanges()),
00489 this, SLOT(slotSaveShortcutFileChanges()));
00490 int res = d->connDialog->exec();
00491 if (res == QDialog::Accepted) {
00492
00493 *m_projectData = d->connDialog->currentProjectData();
00494 }
00495
00496 delete d->connDialog;
00497 d->connDialog = 0;
00498 delete d->shortcutFile;
00499 d->shortcutFile = 0;
00500
00501 if (res == QDialog::Rejected) {
00502 delete m_projectData;
00503 m_projectData = 0;
00504 return cancelled;
00505 }
00506 }
00507 else if (cdata.driverName=="connection") {
00508
00509 d->connShortcutFile = new KexiDBConnShortcutFile(cdata.fileName());
00510 if (!d->connShortcutFile->loadConnectionData(cdata, &d->shortcutFileGroupKey)) {
00511 KMessageBox::sorry(0, i18n("Could not open connection data file\n\"%1\".")
00512 .arg(QDir::convertSeparators(cdata.fileName())));
00513 delete d->connShortcutFile;
00514 d->connShortcutFile = 0;
00515 return false;
00516 }
00517 bool cancel = false;
00518 const bool showConnectionDialog = !args->isSet("skip-dialog");
00519 while (true) {
00520 if (showConnectionDialog) {
00521
00522 if (!d->connDialog) {
00523 d->connDialog = new KexiDBConnectionDialog(
00524 cdata, d->connShortcutFile->fileName());
00525 connect(d->connDialog, SIGNAL(saveChanges()),
00526 this, SLOT(slotSaveShortcutFileChanges()));
00527 }
00528 const int res = d->connDialog->exec();
00529 if (res == QDialog::Accepted) {
00530
00531 cdata = *d->connDialog->currentProjectData().constConnectionData();
00532 }
00533 else {
00534 cancel = true;
00535 break;
00536 }
00537 }
00538 m_projectData = selectProject(&cdata, cancel);
00539 if (m_projectData || cancel || !showConnectionDialog)
00540 break;
00541 }
00542
00543 delete d->connShortcutFile;
00544 d->connShortcutFile = 0;
00545 delete d->connDialog;
00546 d->connDialog = 0;
00547
00548 if (cancel)
00549 return cancelled;
00550 }
00551 else
00552 m_projectData = new KexiProjectData(cdata, prjName);
00553 }
00554 else
00555 m_projectData = new KexiProjectData(cdata, prjName);
00556
00557 }
00558
00559
00560 }
00561 if (args->count()>1) {
00562
00563 }
00564
00565
00566 if (d->passwordDialog && d->passwordDialog->showConnectionDetailsRequested()) {
00567 d->connDialog = new KexiDBConnectionDialog(*m_projectData);
00568
00569
00570 int res = d->connDialog->exec();
00571
00572 if (res == QDialog::Accepted) {
00573
00574 *m_projectData = d->connDialog->currentProjectData();
00575 }
00576
00577 delete d->connDialog;
00578 d->connDialog = 0;
00579
00580 if (res == QDialog::Rejected) {
00581 delete m_projectData;
00582 m_projectData = 0;
00583 return cancelled;
00584 }
00585 }
00586
00587
00588 const bool atLeastOneAOOFound = getAutoopenObjects(args, "open")
00589 || getAutoopenObjects(args, "design")
00590 || getAutoopenObjects(args, "edittext")
00591 || getAutoopenObjects(args, "new")
00592 || getAutoopenObjects(args, "print")
00593 || getAutoopenObjects(args, "print-preview");
00594
00595 if (atLeastOneAOOFound && !openExisting) {
00596 KMessageBox::information( 0,
00597 i18n("You have specified a few database objects to be opened automatically, "
00598 "using startup options.\n"
00599 "These options will be ignored because it is not available while creating "
00600 "or dropping projects."));
00601 }
00602
00603 if (createDB) {
00604 bool creationNancelled;
00605 KexiGUIMessageHandler gui;
00606 KexiProject *prj = KexiProject::createBlankProject(creationNancelled, projectData(), &gui);
00607 bool ok = prj!=0;
00608 delete prj;
00609 if (creationNancelled)
00610 return cancelled;
00611 if (!alsoOpenDB) {
00612 if (ok) {
00613 KMessageBox::information( 0, i18n("Project \"%1\" created successfully.")
00614 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00615 }
00616 return ok;
00617 }
00618 }
00619 else if (dropDB) {
00620 KexiGUIMessageHandler gui;
00621 tristate res = KexiProject::dropProject(projectData(), &gui, false);
00622 if (res)
00623 KMessageBox::information( 0, i18n("Project \"%1\" dropped successfully.")
00624 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00625 return res!=false;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 if (!m_projectData) {
00637 cdata = KexiDB::ConnectionData();
00638
00639 if (!KexiStartupDialog::shouldBeShown())
00640 return true;
00641
00642 if (!d->startupDialog) {
00643
00644 d->startupDialog = new KexiStartupDialog(
00645 KexiStartupDialog::Everything, KexiStartupDialog::CheckBoxDoNotShowAgain,
00646 Kexi::connset(), Kexi::recentProjects(), 0, "KexiStartupDialog");
00647 }
00648 if (d->startupDialog->exec()!=QDialog::Accepted)
00649 return true;
00650
00651 int r = d->startupDialog->result();
00652 if (r==KexiStartupDialog::TemplateResult) {
00653
00654 QString selectedTemplateKey( d->startupDialog->selectedTemplateKey() );
00655 if (selectedTemplateKey=="blank") {
00656 m_action = CreateBlankProject;
00657 return true;
00658 }
00659 else if (selectedTemplateKey=="import") {
00660 m_action = ImportProject;
00661 return true;
00662 }
00663
00665 return true;
00666 }
00667 else if (r==KexiStartupDialog::OpenExistingResult) {
00668
00669 QString selFile = d->startupDialog->selectedExistingFile();
00670 if (!selFile.isEmpty()) {
00671
00672
00673 cdata.setFileName( selFile );
00674 QString detectedDriverName;
00675 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00676 cdata.driverName, selFile );
00677 if (true != res)
00678 return res;
00679 if (m_importActionData) {
00680 m_action = ImportProject;
00681 return true;
00682 }
00683
00684 if (detectedDriverName.isEmpty())
00685 return false;
00686 cdata.driverName = detectedDriverName;
00687 m_projectData = new KexiProjectData(cdata, selFile);
00688 }
00689 else if (d->startupDialog->selectedExistingConnection()) {
00690
00691
00692 KexiDB::ConnectionData *cdata = d->startupDialog->selectedExistingConnection();
00693
00694 bool cancelled;
00695 m_projectData = selectProject( cdata, cancelled );
00696 if (!m_projectData && !cancelled || cancelled) {
00697
00698 return init(0, 0);
00699 }
00700
00701 delete d->startupDialog;
00702 d->startupDialog = 0;
00703 }
00704 }
00705 else if (r==KexiStartupDialog::OpenRecentResult) {
00706
00707 const KexiProjectData *data = d->startupDialog->selectedProjectData();
00708 if (data) {
00709
00710
00711 }
00713 return data!=0;
00714 }
00715
00716 if (!m_projectData)
00717 return true;
00718 }
00719
00720 if (m_projectData && (openExisting || (createDB && alsoOpenDB))) {
00721 m_action = OpenProject;
00722 }
00723
00724
00725
00726 return true;
00727 }
00728
00729 tristate KexiStartupHandler::detectActionForFile(
00730 KexiStartupData::Import& detectedImportAction, QString& detectedDriverName,
00731 const QString& _suggestedDriverName, const QString &dbFileName, QWidget *parent, int options )
00732 {
00733 detectedImportAction = KexiStartupData::Import();
00734 QString suggestedDriverName(_suggestedDriverName);
00735 detectedDriverName = QString::null;
00736 QFileInfo finfo(dbFileName);
00737 if (dbFileName.isEmpty() || !finfo.isReadable()) {
00738 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00739 +i18n("<p>The file <nobr>\"%1\"</nobr> does not exist or is not readable.</p>")
00740 .arg(QDir::convertSeparators(dbFileName))
00741 +i18n("Check the file's permissions and whether it is already opened "
00742 "and locked by another application."));
00743 return false;
00744 }
00745
00746 KMimeType::Ptr ptr;
00747 QString mimename;
00748
00749 const bool thisIsShortcut = (options & ThisIsAShortcutToAProjectFile)
00750 || (options & ThisIsAShortcutToAConnectionData);
00751
00752 if ((options & ThisIsAProjectFile) || !thisIsShortcut) {
00753
00754 ptr = KMimeType::findByFileContent(dbFileName);
00755 mimename = ptr.data()->name();
00756 kdDebug() << "KexiStartupHandler::detectActionForFile(): found mime is: "
00757 << mimename << endl;
00758 if (mimename.isEmpty() || mimename=="application/octet-stream" || mimename=="text/plain") {
00759
00760 ptr = KMimeType::findByURL(dbFileName);
00761 mimename = ptr.data()->name();
00762 }
00763 }
00764 if (mimename.isEmpty() || mimename=="application/octet-stream") {
00765
00766 QFile f(dbFileName);
00767 if (!f.open(IO_ReadOnly)) {
00768
00769 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00770 +i18n("<p>The file <nobr>\"%1\"</nobr> is not readable.</p>")
00771 .arg(QDir::convertSeparators(dbFileName))
00772 +i18n("Check the file's permissions and whether it is already opened "
00773 "and locked by another application."));
00774 return false;
00775 }
00776 }
00777 if ((options & ThisIsAShortcutToAProjectFile) || mimename=="application/x-kexiproject-shortcut") {
00778 detectedDriverName = "shortcut";
00779 return true;
00780 }
00781
00782 if ((options & ThisIsAShortcutToAConnectionData) || mimename=="application/x-kexi-connectiondata") {
00783 detectedDriverName = "connection";
00784 return true;
00785 }
00786
00789 if (ptr.data()) {
00790 if (mimename=="application/x-msaccess") {
00791 if (KMessageBox::Yes != KMessageBox::questionYesNo(parent, i18n(
00792 "\"%1\" is an external file of type:\n\"%2\".\n"
00793 "Do you want to import the file as a Kexi project?")
00794 .arg(QDir::convertSeparators(dbFileName)).arg(ptr.data()->comment()),
00795 i18n("Open External File"), KGuiItem(i18n("Import...")), KStdGuiItem::cancel() ) )
00796 {
00797 return cancelled;
00798 }
00799 detectedImportAction.mimeType = mimename;
00800 detectedImportAction.fileName = dbFileName;
00801 return true;
00802 }
00803 }
00804
00805 if (!finfo.isWritable()) {
00807 }
00808
00809
00810 QString tmpDriverName = Kexi::driverManager().lookupByMime(mimename).latin1();
00811
00812 bool useDetectedDriver = suggestedDriverName.isEmpty() || suggestedDriverName.lower()==detectedDriverName.lower();
00813 if (!useDetectedDriver) {
00814 int res = KMessageBox::warningYesNoCancel(parent, i18n(
00815 "The project file \"%1\" is recognized as compatible with \"%2\" database driver, "
00816 "while you have asked for \"%3\" database driver to be used.\n"
00817 "Do you want to use \"%4\" database driver?")
00818 .arg(QDir::convertSeparators(dbFileName))
00819 .arg(tmpDriverName).arg(suggestedDriverName).arg(tmpDriverName));
00820 if (KMessageBox::Yes == res)
00821 useDetectedDriver = true;
00822 else if (KMessageBox::Cancel == res)
00823 return cancelled;
00824 }
00825 if (useDetectedDriver) {
00826 detectedDriverName = tmpDriverName;
00827 }
00828 else {
00829 detectedDriverName = suggestedDriverName;
00830 }
00831
00832
00833 const QString newFileFormat = "SQLite3";
00834 if (!(options & DontConvert)
00835 && detectedDriverName.lower()=="sqlite2" && detectedDriverName.lower()!=suggestedDriverName.lower()
00836 && KMessageBox::Yes == KMessageBox::questionYesNo(parent, i18n(
00837 "Previous version of database file format (\"%1\") is detected in the \"%2\" "
00838 "project file.\nDo you want to convert the project to a new \"%3\" format (recommended)?")
00839 .arg(detectedDriverName).arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat)) )
00840 {
00841
00842 SQLite2ToSQLite3Migration migr( finfo.absFilePath() );
00843 tristate res = migr.run();
00844
00845 if (!res) {
00846
00847 KMessageBox::sorry(parent, i18n(
00848 "Failed to convert project file \"%1\" to a new \"%2\" format.\n"
00849 "The file format remains unchanged.")
00850 .arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat) );
00851
00852 }
00853 if (res)
00854 detectedDriverName = newFileFormat;
00855 }
00856
00857 if (detectedDriverName.isEmpty()) {
00858 QString possibleProblemsInfoMsg( Kexi::driverManager().possibleProblemsInfoMsg() );
00859 if (!possibleProblemsInfoMsg.isEmpty()) {
00860 possibleProblemsInfoMsg.prepend(QString::fromLatin1("<p>")+i18n("Possible problems:"));
00861 possibleProblemsInfoMsg += QString::fromLatin1("</p>");
00862 }
00863 KMessageBox::detailedSorry(parent,
00864 i18n( "The file \"%1\" is not recognized as being supported by Kexi.")
00865 .arg(QDir::convertSeparators(dbFileName)),
00866 QString::fromLatin1("<p>")
00867 +i18n("Database driver for this file type not found.\nDetected MIME type: %1")
00868 .arg(mimename)
00869 +(ptr.data()->comment().isEmpty()
00870 ? QString::fromLatin1(".") : QString::fromLatin1(" (%1).").arg(ptr.data()->comment()))
00871 +QString::fromLatin1("</p>")
00872 +possibleProblemsInfoMsg);
00873 return false;
00874 }
00875 return true;
00876 }
00877
00878 KexiProjectData*
00879 KexiStartupHandler::selectProject(KexiDB::ConnectionData *cdata, bool& cancelled, QWidget *parent)
00880 {
00881 clearStatus();
00882 cancelled = false;
00883 if (!cdata)
00884 return 0;
00885 if (!cdata->savePassword && cdata->password.isEmpty()) {
00886 if (!d->passwordDialog)
00887 d->passwordDialog = new KexiDBPasswordDialog(0, *cdata, false);
00888 const int ret = d->passwordDialog->exec();
00889 if (d->passwordDialog->showConnectionDetailsRequested() || ret == QDialog::Accepted) {
00890
00891 } else {
00892 cancelled = true;
00893 return 0;
00894 }
00895 }
00896 KexiProjectData* projectData = 0;
00897
00898 KexiProjectSelectorDialog prjdlg( parent, "prjdlg", cdata, true, false );
00899 if (!prjdlg.projectSet() || prjdlg.projectSet()->error()) {
00900 KexiGUIMessageHandler msgh;
00901 if (prjdlg.projectSet())
00902 msgh.showErrorMessage(prjdlg.projectSet(),
00903 i18n("Could not load list of available projects for <b>%1</b> database server.")
00904 .arg(cdata->serverInfoString(true)));
00905 else
00906 msgh.showErrorMessage(
00907 i18n("Could not load list of available projects for <b>%1</b> database server.")
00908 .arg(cdata->serverInfoString(true)));
00909
00910
00911 return 0;
00912 }
00913 if (prjdlg.exec()!=QDialog::Accepted) {
00914 cancelled = true;
00915 return 0;
00916 }
00917 if (prjdlg.selectedProjectData()) {
00918
00919 projectData = new KexiProjectData(*prjdlg.selectedProjectData());
00920 }
00921 return projectData;
00922 }
00923
00924 void KexiStartupHandler::slotSaveShortcutFileChanges()
00925 {
00926 bool ok = true;
00927 if (d->shortcutFile)
00928 ok = d->shortcutFile->saveProjectData(d->connDialog->currentProjectData(),
00929 d->connDialog->savePasswordOptionSelected(),
00930 &d->shortcutFileGroupKey );
00931 else if (d->connShortcutFile)
00932 ok = d->connShortcutFile->saveConnectionData(
00933 *d->connDialog->currentProjectData().connectionData(),
00934 d->connDialog->savePasswordOptionSelected(),
00935 &d->shortcutFileGroupKey );
00936
00937 if (!ok) {
00938 KMessageBox::sorry(0, i18n("Failed saving connection data to\n\"%1\" file.")
00939 .arg(QDir::convertSeparators(d->shortcutFile->fileName())));
00940 }
00941 }
00942
00943
00944
00945
00946
00947
00948
00949 #include "KexiStartup.moc"