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 QString fileName;
00425 if (fileDriverSelected) {
00426 fileName = QFile::decodeName(args->arg(0));
00427 }
00428 else {
00429 prjName = QString::fromLocal8Bit(args->arg(0));
00430 }
00431
00432 if (fileDriverSelected) {
00433 QFileInfo finfo(fileName);
00434 prjName = finfo.fileName();
00435 cdata.setFileName( finfo.absFilePath() );
00436 projectFileExists = finfo.exists();
00437
00438 if (dropDB && !projectFileExists) {
00439 KMessageBox::sorry(0,
00440 i18n("Could not remove project.\nThe file \"%1\" does not exist.")
00441 .arg(QDir::convertSeparators(cdata.dbFileName())));
00442 return 0;
00443 }
00444 }
00445
00446 if (createDB) {
00447 if (cdata.driverName.isEmpty())
00448 cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName();
00449 m_projectData = new KexiProjectData(cdata, prjName);
00450 }
00451 else {
00452 if (fileDriverSelected) {
00453 int detectOptions = 0;
00454 if (fileType=="project")
00455 detectOptions |= ThisIsAProjectFile;
00456 else if (fileType=="shortcut")
00457 detectOptions |= ThisIsAShortcutToAProjectFile;
00458 else if (fileType=="connection")
00459 detectOptions |= ThisIsAShortcutToAConnectionData;
00460
00461 if (dropDB)
00462 detectOptions |= DontConvert;
00463
00464 QString detectedDriverName;
00465 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00466 cdata.driverName, cdata.fileName(), 0, detectOptions );
00467 if (true != res)
00468 return res;
00469
00470 if (m_importActionData) {
00471 m_action = ImportProject;
00472 return true;
00473 }
00474
00475
00476 cdata.driverName = detectedDriverName;
00477 if (cdata.driverName=="shortcut") {
00478
00479 d->shortcutFile = new KexiDBShortcutFile(cdata.fileName());
00480 m_projectData = new KexiProjectData();
00481 if (!d->shortcutFile->loadProjectData(*m_projectData, &d->shortcutFileGroupKey)) {
00482 KMessageBox::sorry(0, i18n("Could not open shortcut file\n\"%1\".")
00483 .arg(QDir::convertSeparators(cdata.fileName())));
00484 delete m_projectData;
00485 m_projectData = 0;
00486 delete d->shortcutFile;
00487 d->shortcutFile = 0;
00488 return false;
00489 }
00490 d->connDialog = new KexiDBConnectionDialog(
00491 *m_projectData, d->shortcutFile->fileName());
00492 connect(d->connDialog, SIGNAL(saveChanges()),
00493 this, SLOT(slotSaveShortcutFileChanges()));
00494 int res = d->connDialog->exec();
00495 if (res == QDialog::Accepted) {
00496
00497 *m_projectData = d->connDialog->currentProjectData();
00498 }
00499
00500 delete d->connDialog;
00501 d->connDialog = 0;
00502 delete d->shortcutFile;
00503 d->shortcutFile = 0;
00504
00505 if (res == QDialog::Rejected) {
00506 delete m_projectData;
00507 m_projectData = 0;
00508 return cancelled;
00509 }
00510 }
00511 else if (cdata.driverName=="connection") {
00512
00513 d->connShortcutFile = new KexiDBConnShortcutFile(cdata.fileName());
00514 if (!d->connShortcutFile->loadConnectionData(cdata, &d->shortcutFileGroupKey)) {
00515 KMessageBox::sorry(0, i18n("Could not open connection data file\n\"%1\".")
00516 .arg(QDir::convertSeparators(cdata.fileName())));
00517 delete d->connShortcutFile;
00518 d->connShortcutFile = 0;
00519 return false;
00520 }
00521 bool cancel = false;
00522 const bool showConnectionDialog = !args->isSet("skip-dialog");
00523 while (true) {
00524 if (showConnectionDialog) {
00525
00526 if (!d->connDialog) {
00527 d->connDialog = new KexiDBConnectionDialog(
00528 cdata, d->connShortcutFile->fileName());
00529 connect(d->connDialog, SIGNAL(saveChanges()),
00530 this, SLOT(slotSaveShortcutFileChanges()));
00531 }
00532 const int res = d->connDialog->exec();
00533 if (res == QDialog::Accepted) {
00534
00535 cdata = *d->connDialog->currentProjectData().constConnectionData();
00536 }
00537 else {
00538 cancel = true;
00539 break;
00540 }
00541 }
00542 m_projectData = selectProject(&cdata, cancel);
00543 if (m_projectData || cancel || !showConnectionDialog)
00544 break;
00545 }
00546
00547 delete d->connShortcutFile;
00548 d->connShortcutFile = 0;
00549 delete d->connDialog;
00550 d->connDialog = 0;
00551
00552 if (cancel)
00553 return cancelled;
00554 }
00555 else
00556 m_projectData = new KexiProjectData(cdata, prjName);
00557 }
00558 else
00559 m_projectData = new KexiProjectData(cdata, prjName);
00560
00561 }
00562
00563
00564 }
00565 if (args->count()>1) {
00566
00567 }
00568
00569
00570 if (d->passwordDialog && d->passwordDialog->showConnectionDetailsRequested()) {
00571 d->connDialog = new KexiDBConnectionDialog(*m_projectData);
00572
00573
00574 int res = d->connDialog->exec();
00575
00576 if (res == QDialog::Accepted) {
00577
00578 *m_projectData = d->connDialog->currentProjectData();
00579 }
00580
00581 delete d->connDialog;
00582 d->connDialog = 0;
00583
00584 if (res == QDialog::Rejected) {
00585 delete m_projectData;
00586 m_projectData = 0;
00587 return cancelled;
00588 }
00589 }
00590
00591
00592 const bool atLeastOneAOOFound = getAutoopenObjects(args, "open")
00593 || getAutoopenObjects(args, "design")
00594 || getAutoopenObjects(args, "edittext")
00595 || getAutoopenObjects(args, "new")
00596 || getAutoopenObjects(args, "print")
00597 || getAutoopenObjects(args, "print-preview");
00598
00599 if (atLeastOneAOOFound && !openExisting) {
00600 KMessageBox::information( 0,
00601 i18n("You have specified a few database objects to be opened automatically, "
00602 "using startup options.\n"
00603 "These options will be ignored because it is not available while creating "
00604 "or dropping projects."));
00605 }
00606
00607 if (createDB) {
00608 bool creationNancelled;
00609 KexiGUIMessageHandler gui;
00610 KexiProject *prj = KexiProject::createBlankProject(creationNancelled, projectData(), &gui);
00611 bool ok = prj!=0;
00612 delete prj;
00613 if (creationNancelled)
00614 return cancelled;
00615 if (!alsoOpenDB) {
00616 if (ok) {
00617 KMessageBox::information( 0, i18n("Project \"%1\" created successfully.")
00618 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00619 }
00620 return ok;
00621 }
00622 }
00623 else if (dropDB) {
00624 KexiGUIMessageHandler gui;
00625 tristate res = KexiProject::dropProject(projectData(), &gui, false);
00626 if (res)
00627 KMessageBox::information( 0, i18n("Project \"%1\" dropped successfully.")
00628 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00629 return res!=false;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 if (!m_projectData) {
00641 cdata = KexiDB::ConnectionData();
00642
00643 if (!KexiStartupDialog::shouldBeShown())
00644 return true;
00645
00646 if (!d->startupDialog) {
00647
00648 d->startupDialog = new KexiStartupDialog(
00649 KexiStartupDialog::Everything, KexiStartupDialog::CheckBoxDoNotShowAgain,
00650 Kexi::connset(), Kexi::recentProjects(), 0, "KexiStartupDialog");
00651 }
00652 if (d->startupDialog->exec()!=QDialog::Accepted)
00653 return true;
00654
00655 int r = d->startupDialog->result();
00656 if (r==KexiStartupDialog::TemplateResult) {
00657
00658 QString selectedTemplateKey( d->startupDialog->selectedTemplateKey() );
00659 if (selectedTemplateKey=="blank") {
00660 m_action = CreateBlankProject;
00661 return true;
00662 }
00663 else if (selectedTemplateKey=="import") {
00664 m_action = ImportProject;
00665 return true;
00666 }
00667
00669 return true;
00670 }
00671 else if (r==KexiStartupDialog::OpenExistingResult) {
00672
00673 QString selFile = d->startupDialog->selectedExistingFile();
00674 if (!selFile.isEmpty()) {
00675
00676
00677 cdata.setFileName( selFile );
00678 QString detectedDriverName;
00679 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00680 cdata.driverName, selFile );
00681 if (true != res)
00682 return res;
00683 if (m_importActionData) {
00684 m_action = ImportProject;
00685 return true;
00686 }
00687
00688 if (detectedDriverName.isEmpty())
00689 return false;
00690 cdata.driverName = detectedDriverName;
00691 m_projectData = new KexiProjectData(cdata, selFile);
00692 }
00693 else if (d->startupDialog->selectedExistingConnection()) {
00694
00695
00696 KexiDB::ConnectionData *cdata = d->startupDialog->selectedExistingConnection();
00697
00698 bool cancelled;
00699 m_projectData = selectProject( cdata, cancelled );
00700 if (!m_projectData && !cancelled || cancelled) {
00701
00702 return init(0, 0);
00703 }
00704
00705 delete d->startupDialog;
00706 d->startupDialog = 0;
00707 }
00708 }
00709 else if (r==KexiStartupDialog::OpenRecentResult) {
00710
00711 const KexiProjectData *data = d->startupDialog->selectedProjectData();
00712 if (data) {
00713
00714
00715 }
00717 return data!=0;
00718 }
00719
00720 if (!m_projectData)
00721 return true;
00722 }
00723
00724 if (m_projectData && (openExisting || (createDB && alsoOpenDB))) {
00725 m_action = OpenProject;
00726 }
00727
00728
00729
00730 return true;
00731 }
00732
00733 tristate KexiStartupHandler::detectActionForFile(
00734 KexiStartupData::Import& detectedImportAction, QString& detectedDriverName,
00735 const QString& _suggestedDriverName, const QString &dbFileName, QWidget *parent, int options )
00736 {
00737 detectedImportAction = KexiStartupData::Import();
00738 QString suggestedDriverName(_suggestedDriverName);
00739 detectedDriverName = QString::null;
00740 QFileInfo finfo(dbFileName);
00741 if (dbFileName.isEmpty() || !finfo.isReadable()) {
00742 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00743 +i18n("<p>The file <nobr>\"%1\"</nobr> does not exist or is not readable.</p>")
00744 .arg(QDir::convertSeparators(dbFileName))
00745 +i18n("Check the file's permissions and whether it is already opened "
00746 "and locked by another application."));
00747 return false;
00748 }
00749
00750 KMimeType::Ptr ptr;
00751 QString mimename;
00752
00753 const bool thisIsShortcut = (options & ThisIsAShortcutToAProjectFile)
00754 || (options & ThisIsAShortcutToAConnectionData);
00755
00756 if ((options & ThisIsAProjectFile) || !thisIsShortcut) {
00757
00758 ptr = KMimeType::findByFileContent(dbFileName);
00759 mimename = ptr.data()->name();
00760 kdDebug() << "KexiStartupHandler::detectActionForFile(): found mime is: "
00761 << mimename << endl;
00762 if (mimename.isEmpty() || mimename=="application/octet-stream" || mimename=="text/plain") {
00763
00764 ptr = KMimeType::findByURL(dbFileName);
00765 mimename = ptr.data()->name();
00766 }
00767 }
00768 if (mimename.isEmpty() || mimename=="application/octet-stream") {
00769
00770 QFile f(dbFileName);
00771 if (!f.open(IO_ReadOnly)) {
00772
00773 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00774 +i18n("<p>The file <nobr>\"%1\"</nobr> is not readable.</p>")
00775 .arg(QDir::convertSeparators(dbFileName))
00776 +i18n("Check the file's permissions and whether it is already opened "
00777 "and locked by another application."));
00778 return false;
00779 }
00780 }
00781 if ((options & ThisIsAShortcutToAProjectFile) || mimename=="application/x-kexiproject-shortcut") {
00782 detectedDriverName = "shortcut";
00783 return true;
00784 }
00785
00786 if ((options & ThisIsAShortcutToAConnectionData) || mimename=="application/x-kexi-connectiondata") {
00787 detectedDriverName = "connection";
00788 return true;
00789 }
00790
00793 if (ptr.data()) {
00794 if (mimename=="application/x-msaccess") {
00795 if (KMessageBox::Yes != KMessageBox::questionYesNo(parent, i18n(
00796 "\"%1\" is an external file of type:\n\"%2\".\n"
00797 "Do you want to import the file as a Kexi project?")
00798 .arg(QDir::convertSeparators(dbFileName)).arg(ptr.data()->comment()),
00799 i18n("Open External File"), KGuiItem(i18n("Import...")), KStdGuiItem::cancel() ) )
00800 {
00801 return cancelled;
00802 }
00803 detectedImportAction.mimeType = mimename;
00804 detectedImportAction.fileName = dbFileName;
00805 return true;
00806 }
00807 }
00808
00809 if (!finfo.isWritable()) {
00811 }
00812
00813
00814 QString tmpDriverName = Kexi::driverManager().lookupByMime(mimename).latin1();
00815
00816 bool useDetectedDriver = suggestedDriverName.isEmpty() || suggestedDriverName.lower()==detectedDriverName.lower();
00817 if (!useDetectedDriver) {
00818 int res = KMessageBox::warningYesNoCancel(parent, i18n(
00819 "The project file \"%1\" is recognized as compatible with \"%2\" database driver, "
00820 "while you have asked for \"%3\" database driver to be used.\n"
00821 "Do you want to use \"%4\" database driver?")
00822 .arg(QDir::convertSeparators(dbFileName))
00823 .arg(tmpDriverName).arg(suggestedDriverName).arg(tmpDriverName));
00824 if (KMessageBox::Yes == res)
00825 useDetectedDriver = true;
00826 else if (KMessageBox::Cancel == res)
00827 return cancelled;
00828 }
00829 if (useDetectedDriver) {
00830 detectedDriverName = tmpDriverName;
00831 }
00832 else {
00833 detectedDriverName = suggestedDriverName;
00834 }
00835
00836
00837 const QString newFileFormat = "SQLite3";
00838 if (!(options & DontConvert)
00839 && detectedDriverName.lower()=="sqlite2" && detectedDriverName.lower()!=suggestedDriverName.lower()
00840 && KMessageBox::Yes == KMessageBox::questionYesNo(parent, i18n(
00841 "Previous version of database file format (\"%1\") is detected in the \"%2\" "
00842 "project file.\nDo you want to convert the project to a new \"%3\" format (recommended)?")
00843 .arg(detectedDriverName).arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat)) )
00844 {
00845
00846 SQLite2ToSQLite3Migration migr( finfo.absFilePath() );
00847 tristate res = migr.run();
00848
00849 if (!res) {
00850
00851 KMessageBox::sorry(parent, i18n(
00852 "Failed to convert project file \"%1\" to a new \"%2\" format.\n"
00853 "The file format remains unchanged.")
00854 .arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat) );
00855
00856 }
00857 if (res)
00858 detectedDriverName = newFileFormat;
00859 }
00860
00861 if (detectedDriverName.isEmpty()) {
00862 QString possibleProblemsInfoMsg( Kexi::driverManager().possibleProblemsInfoMsg() );
00863 if (!possibleProblemsInfoMsg.isEmpty()) {
00864 possibleProblemsInfoMsg.prepend(QString::fromLatin1("<p>")+i18n("Possible problems:"));
00865 possibleProblemsInfoMsg += QString::fromLatin1("</p>");
00866 }
00867 KMessageBox::detailedSorry(parent,
00868 i18n( "The file \"%1\" is not recognized as being supported by Kexi.")
00869 .arg(QDir::convertSeparators(dbFileName)),
00870 QString::fromLatin1("<p>")
00871 +i18n("Database driver for this file type not found.\nDetected MIME type: %1")
00872 .arg(mimename)
00873 +(ptr.data()->comment().isEmpty()
00874 ? QString::fromLatin1(".") : QString::fromLatin1(" (%1).").arg(ptr.data()->comment()))
00875 +QString::fromLatin1("</p>")
00876 +possibleProblemsInfoMsg);
00877 return false;
00878 }
00879 return true;
00880 }
00881
00882 KexiProjectData*
00883 KexiStartupHandler::selectProject(KexiDB::ConnectionData *cdata, bool& cancelled, QWidget *parent)
00884 {
00885 clearStatus();
00886 cancelled = false;
00887 if (!cdata)
00888 return 0;
00889 if (!cdata->savePassword && cdata->password.isEmpty()) {
00890 if (!d->passwordDialog)
00891 d->passwordDialog = new KexiDBPasswordDialog(0, *cdata, false);
00892 const int ret = d->passwordDialog->exec();
00893 if (d->passwordDialog->showConnectionDetailsRequested() || ret == QDialog::Accepted) {
00894
00895 } else {
00896 cancelled = true;
00897 return 0;
00898 }
00899 }
00900 KexiProjectData* projectData = 0;
00901
00902 KexiProjectSelectorDialog prjdlg( parent, "prjdlg", cdata, true, false );
00903 if (!prjdlg.projectSet() || prjdlg.projectSet()->error()) {
00904 KexiGUIMessageHandler msgh;
00905 if (prjdlg.projectSet())
00906 msgh.showErrorMessage(prjdlg.projectSet(),
00907 i18n("Could not load list of available projects for <b>%1</b> database server.")
00908 .arg(cdata->serverInfoString(true)));
00909 else
00910 msgh.showErrorMessage(
00911 i18n("Could not load list of available projects for <b>%1</b> database server.")
00912 .arg(cdata->serverInfoString(true)));
00913
00914
00915 return 0;
00916 }
00917 if (prjdlg.exec()!=QDialog::Accepted) {
00918 cancelled = true;
00919 return 0;
00920 }
00921 if (prjdlg.selectedProjectData()) {
00922
00923 projectData = new KexiProjectData(*prjdlg.selectedProjectData());
00924 }
00925 return projectData;
00926 }
00927
00928 void KexiStartupHandler::slotSaveShortcutFileChanges()
00929 {
00930 bool ok = true;
00931 if (d->shortcutFile)
00932 ok = d->shortcutFile->saveProjectData(d->connDialog->currentProjectData(),
00933 d->connDialog->savePasswordOptionSelected(),
00934 &d->shortcutFileGroupKey );
00935 else if (d->connShortcutFile)
00936 ok = d->connShortcutFile->saveConnectionData(
00937 *d->connDialog->currentProjectData().connectionData(),
00938 d->connDialog->savePasswordOptionSelected(),
00939 &d->shortcutFileGroupKey );
00940
00941 if (!ok) {
00942 KMessageBox::sorry(0, i18n("Failed saving connection data to\n\"%1\" file.")
00943 .arg(QDir::convertSeparators(d->shortcutFile->fileName())));
00944 }
00945 }
00946
00947
00948
00949
00950
00951
00952
00953 #include "KexiStartup.moc"