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 QString defaultType;
00228 if (action_name=="execute")
00229 defaultType = "macro";
00230 else
00231 defaultType = "table";
00232
00233
00234 if (stripQuotes(item, obj_name)) {
00235 type_name = defaultType;
00236 }
00237 else if ((idx = item.find(':'))!=-1) {
00238
00239 type_name = item.left(idx).lower();
00240 obj_name = item.mid(idx+1);
00241
00242 if (obj_name.left(1)=="\"" && obj_name.right(1)=="\"")
00243 obj_name = obj_name.mid(1, obj_name.length()-2);
00244 }
00245 else {
00246
00247 obj_name = item;
00248 type_name = defaultType;
00249 }
00250 }
00251 if (type_name.isEmpty())
00252 continue;
00253 if (name_required && obj_name.isEmpty())
00254 continue;
00255
00256 KexiProjectData::ObjectInfo info;
00257 info["name"]=obj_name;
00258 info["type"]=type_name;
00259 info["action"]=action_name;
00260
00261 atLeastOneFound = true;
00262 if (projectData())
00263 projectData()->autoopenObjects.append( info );
00264 else
00265 return true;
00266 }
00267 return atLeastOneFound;
00268 }
00269
00270 tristate KexiStartupHandler::init(int , char ** )
00271 {
00272 m_action = DoNothing;
00273
00274 KCmdLineArgs *args = KCmdLineArgs::parsedArgs(0);
00275 if (!args)
00276 return true;
00277
00278 KexiDB::ConnectionData cdata;
00279
00280 const QString connectionShortcutFileName( args->getOption("connection") );
00281 if (!connectionShortcutFileName.isEmpty()) {
00282 KexiDBConnShortcutFile connectionShortcut( connectionShortcutFileName );
00283 if (!connectionShortcut.loadConnectionData(cdata)) {
00286 KMessageBox::sorry( 0, "<qt>"
00287 +i18n("Could not read connection information from connection shortcut "
00288 "file <nobr>\"%1\"</nobr>.<br><br>Check whether the file has valid contents.")
00289 .arg(QDir::convertSeparators(connectionShortcut.fileName())));
00290 return false;
00291 }
00292 }
00293
00294 if (!args->getOption("dbdriver").isEmpty())
00295 cdata.driverName = args->getOption("dbdriver");
00296
00297 QString fileType( args->getOption("type").lower() );
00298 if (args->count()>0 && (!fileType.isEmpty() && fileType!="project" && fileType!="shortcut" && fileType!="connection")) {
00299 KMessageBox::sorry( 0,
00300 i18n("You have specified invalid argument (\"%1\") for \"type\" command-line option.")
00301 .arg(fileType));
00302 return false;
00303 }
00304
00305
00306
00307 #ifdef KEXI_SERVER_SUPPORT
00308 if (!args->getOption("host").isEmpty())
00309 cdata.hostName = args->getOption("host");
00310 if (!args->getOption("local-socket").isEmpty())
00311 cdata.localSocketFileName = args->getOption("local-socket");
00312 if (!args->getOption("user").isEmpty())
00313 cdata.userName = args->getOption("user");
00314 #endif
00315
00316 bool fileDriverSelected;
00317 if (cdata.driverName.isEmpty())
00318 fileDriverSelected = true;
00319 else {
00320 KexiDB::DriverManager dm;
00321 KexiDB::Driver::Info dinfo = dm.driverInfo(cdata.driverName);
00322 if (dinfo.name.isEmpty()) {
00323
00324 KMessageBox::sorry(0, dm.errorMsg());
00325 return false;
00326 }
00327 fileDriverSelected = dinfo.fileBased;
00328 }
00329 bool projectFileExists = false;
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 #ifdef KEXI_SERVER_SUPPORT
00350 const QString portStr = args->getOption("port");
00351 if (!portStr.isEmpty()) {
00352 bool ok;
00353 const int p = portStr.toInt(&ok);
00354 if (ok && p > 0)
00355 cdata.port = p;
00356 else {
00357 KMessageBox::sorry( 0,
00358 i18n("You have specified invalid port number \"%1\"."));
00359 return false;
00360 }
00361 }
00362 #endif
00363
00364 #ifdef KEXI_SHOW_UNIMPLEMENTED
00365 m_forcedFinalMode = args->isSet("final-mode");
00366 m_forcedDesignMode = args->isSet("design-mode");
00367 #else
00368 m_forcedFinalMode = false;
00369 m_forcedDesignMode = false;
00370 #endif
00371 bool createDB = args->isSet("createdb");
00372 const bool alsoOpenDB = args->isSet("create-opendb");
00373 if (alsoOpenDB)
00374 createDB = true;
00375 const bool dropDB = args->isSet("dropdb");
00376 const bool openExisting = !createDB && !dropDB;
00377 const bool readOnly = args->isSet("readonly");
00378 const QString couldnotMsg = QString::fromLatin1("\n")
00379 +i18n("Could not start Kexi application this way.");
00380
00381 if (createDB && dropDB) {
00382 KMessageBox::sorry( 0, i18n(
00383 "You have used both \"createdb\" and \"dropdb\" startup options.")+couldnotMsg);
00384 return false;
00385 };
00386
00387 if (createDB || dropDB) {
00388 if (args->count()<1) {
00389 KMessageBox::sorry( 0, i18n("No project name specified.") );
00390 return false;
00391 }
00392 m_action = Exit;
00393 }
00394
00395
00396
00397 if (!fileDriverSelected && !cdata.driverName.isEmpty() && cdata.password.isEmpty()) {
00398
00399 if (cdata.password.isEmpty()) {
00400 delete d->passwordDialog;
00401 d->passwordDialog = new KexiDBPasswordDialog(0, cdata, true);
00402
00403
00404 const int ret = d->passwordDialog->exec();
00405 if (d->passwordDialog->showConnectionDetailsRequested() || ret == QDialog::Accepted) {
00406
00407
00408
00409
00410 } else {
00411 m_action = Exit;
00412 return true;
00413 }
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422 if (m_forcedFinalMode && m_forcedDesignMode) {
00423 KMessageBox::sorry( 0, i18n(
00424 "You have used both \"final-mode\" and \"design-mode\" startup options.")+couldnotMsg);
00425 return false;
00426 }
00427
00428
00429 if (args->count()>=1) {
00430 QString prjName;
00431 QString fileName;
00432 if (fileDriverSelected) {
00433 fileName = QFile::decodeName(args->arg(0));
00434 }
00435 else {
00436 prjName = QString::fromLocal8Bit(args->arg(0));
00437 }
00438
00439 if (fileDriverSelected) {
00440 QFileInfo finfo(fileName);
00441 prjName = finfo.fileName();
00442 cdata.setFileName( finfo.absFilePath() );
00443 projectFileExists = finfo.exists();
00444
00445 if (dropDB && !projectFileExists) {
00446 KMessageBox::sorry(0,
00447 i18n("Could not remove project.\nThe file \"%1\" does not exist.")
00448 .arg(QDir::convertSeparators(cdata.dbFileName())));
00449 return 0;
00450 }
00451 }
00452
00453 if (createDB) {
00454 if (cdata.driverName.isEmpty())
00455 cdata.driverName = KexiDB::Driver::defaultFileBasedDriverName();
00456 m_projectData = new KexiProjectData(cdata, prjName);
00457 }
00458 else {
00459 if (fileDriverSelected) {
00460 int detectOptions = 0;
00461 if (fileType=="project")
00462 detectOptions |= ThisIsAProjectFile;
00463 else if (fileType=="shortcut")
00464 detectOptions |= ThisIsAShortcutToAProjectFile;
00465 else if (fileType=="connection")
00466 detectOptions |= ThisIsAShortcutToAConnectionData;
00467
00468 if (dropDB)
00469 detectOptions |= DontConvert;
00470
00471 QString detectedDriverName;
00472 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00473 cdata.driverName, cdata.fileName(), 0, detectOptions );
00474 if (true != res)
00475 return res;
00476
00477 if (m_importActionData) {
00478 m_action = ImportProject;
00479 return true;
00480 }
00481
00482
00483 cdata.driverName = detectedDriverName;
00484 if (cdata.driverName=="shortcut") {
00485
00486 d->shortcutFile = new KexiDBShortcutFile(cdata.fileName());
00487 m_projectData = new KexiProjectData();
00488 if (!d->shortcutFile->loadProjectData(*m_projectData, &d->shortcutFileGroupKey)) {
00489 KMessageBox::sorry(0, i18n("Could not open shortcut file\n\"%1\".")
00490 .arg(QDir::convertSeparators(cdata.fileName())));
00491 delete m_projectData;
00492 m_projectData = 0;
00493 delete d->shortcutFile;
00494 d->shortcutFile = 0;
00495 return false;
00496 }
00497 d->connDialog = new KexiDBConnectionDialog(
00498 *m_projectData, d->shortcutFile->fileName());
00499 connect(d->connDialog, SIGNAL(saveChanges()),
00500 this, SLOT(slotSaveShortcutFileChanges()));
00501 int res = d->connDialog->exec();
00502 if (res == QDialog::Accepted) {
00503
00504 *m_projectData = d->connDialog->currentProjectData();
00505 }
00506
00507 delete d->connDialog;
00508 d->connDialog = 0;
00509 delete d->shortcutFile;
00510 d->shortcutFile = 0;
00511
00512 if (res == QDialog::Rejected) {
00513 delete m_projectData;
00514 m_projectData = 0;
00515 return cancelled;
00516 }
00517 }
00518 else if (cdata.driverName=="connection") {
00519
00520 d->connShortcutFile = new KexiDBConnShortcutFile(cdata.fileName());
00521 if (!d->connShortcutFile->loadConnectionData(cdata, &d->shortcutFileGroupKey)) {
00522 KMessageBox::sorry(0, i18n("Could not open connection data file\n\"%1\".")
00523 .arg(QDir::convertSeparators(cdata.fileName())));
00524 delete d->connShortcutFile;
00525 d->connShortcutFile = 0;
00526 return false;
00527 }
00528 bool cancel = false;
00529 const bool showConnectionDialog = !args->isSet("skip-conn-dialog");
00530 while (true) {
00531 if (showConnectionDialog) {
00532
00533 if (!d->connDialog) {
00534 d->connDialog = new KexiDBConnectionDialog(
00535 cdata, d->connShortcutFile->fileName());
00536 connect(d->connDialog, SIGNAL(saveChanges()),
00537 this, SLOT(slotSaveShortcutFileChanges()));
00538 }
00539 const int res = d->connDialog->exec();
00540 if (res == QDialog::Accepted) {
00541
00542 cdata = *d->connDialog->currentProjectData().constConnectionData();
00543 }
00544 else {
00545 cancel = true;
00546 break;
00547 }
00548 }
00549 m_projectData = selectProject(&cdata, cancel);
00550 if (m_projectData || cancel || !showConnectionDialog)
00551 break;
00552 }
00553
00554 delete d->connShortcutFile;
00555 d->connShortcutFile = 0;
00556 delete d->connDialog;
00557 d->connDialog = 0;
00558
00559 if (cancel)
00560 return cancelled;
00561 }
00562 else
00563 m_projectData = new KexiProjectData(cdata, prjName);
00564 }
00565 else
00566 m_projectData = new KexiProjectData(cdata, prjName);
00567
00568 }
00569
00570
00571 }
00572 if (args->count()>1) {
00573
00574 }
00575
00576
00577 if (d->passwordDialog && d->passwordDialog->showConnectionDetailsRequested()) {
00578 d->connDialog = new KexiDBConnectionDialog(*m_projectData);
00579
00580
00581 int res = d->connDialog->exec();
00582
00583 if (res == QDialog::Accepted) {
00584
00585 *m_projectData = d->connDialog->currentProjectData();
00586 }
00587
00588 delete d->connDialog;
00589 d->connDialog = 0;
00590
00591 if (res == QDialog::Rejected) {
00592 delete m_projectData;
00593 m_projectData = 0;
00594 return cancelled;
00595 }
00596 }
00597
00598
00599 const bool atLeastOneAOOFound = getAutoopenObjects(args, "open")
00600 || getAutoopenObjects(args, "design")
00601 || getAutoopenObjects(args, "edittext")
00602 || getAutoopenObjects(args, "execute")
00603 || getAutoopenObjects(args, "new")
00604 || getAutoopenObjects(args, "print")
00605 || getAutoopenObjects(args, "print-preview");
00606
00607 if (atLeastOneAOOFound && !openExisting) {
00608 KMessageBox::information( 0,
00609 i18n("You have specified a few database objects to be opened automatically, "
00610 "using startup options.\n"
00611 "These options will be ignored because it is not available while creating "
00612 "or dropping projects."));
00613 }
00614
00615 if (createDB) {
00616 bool creationNancelled;
00617 KexiGUIMessageHandler gui;
00618 KexiProject *prj = KexiProject::createBlankProject(creationNancelled, projectData(), &gui);
00619 bool ok = prj!=0;
00620 delete prj;
00621 if (creationNancelled)
00622 return cancelled;
00623 if (!alsoOpenDB) {
00624 if (ok) {
00625 KMessageBox::information( 0, i18n("Project \"%1\" created successfully.")
00626 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00627 }
00628 return ok;
00629 }
00630 }
00631 else if (dropDB) {
00632 KexiGUIMessageHandler gui;
00633 tristate res = KexiProject::dropProject(projectData(), &gui, false);
00634 if (res==true)
00635 KMessageBox::information( 0, i18n("Project \"%1\" dropped successfully.")
00636 .arg( QDir::convertSeparators(projectData()->databaseName()) ));
00637 return res!=false;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 if (!m_projectData) {
00649 cdata = KexiDB::ConnectionData();
00650
00651 if (args->isSet("skip-startup-dialog") || !KexiStartupDialog::shouldBeShown())
00652 return true;
00653
00654 if (!d->startupDialog) {
00655
00656 d->startupDialog = new KexiStartupDialog(
00657 KexiStartupDialog::Everything, KexiStartupDialog::CheckBoxDoNotShowAgain,
00658 Kexi::connset(), Kexi::recentProjects(), 0, "KexiStartupDialog");
00659 }
00660 if (d->startupDialog->exec()!=QDialog::Accepted)
00661 return true;
00662
00663 int r = d->startupDialog->result();
00664 if (r==KexiStartupDialog::TemplateResult) {
00665
00666 QString selectedTemplateKey( d->startupDialog->selectedTemplateKey() );
00667 if (selectedTemplateKey=="blank") {
00668 m_action = CreateBlankProject;
00669 return true;
00670 }
00671 else if (selectedTemplateKey=="import") {
00672 m_action = ImportProject;
00673 return true;
00674 }
00675
00677 return true;
00678 }
00679 else if (r==KexiStartupDialog::OpenExistingResult) {
00680
00681 QString selFile = d->startupDialog->selectedExistingFile();
00682 if (!selFile.isEmpty()) {
00683
00684
00685 cdata.setFileName( selFile );
00686 QString detectedDriverName;
00687 const tristate res = detectActionForFile( m_importActionData, detectedDriverName,
00688 cdata.driverName, selFile );
00689 if (true != res)
00690 return res;
00691 if (m_importActionData) {
00692 m_action = ImportProject;
00693 return true;
00694 }
00695
00696 if (detectedDriverName.isEmpty())
00697 return false;
00698 cdata.driverName = detectedDriverName;
00699 m_projectData = new KexiProjectData(cdata, selFile);
00700 }
00701 else if (d->startupDialog->selectedExistingConnection()) {
00702
00703
00704 KexiDB::ConnectionData *cdata = d->startupDialog->selectedExistingConnection();
00705
00706 bool cancelled;
00707 m_projectData = selectProject( cdata, cancelled );
00708 if (!m_projectData && !cancelled || cancelled) {
00709
00710 return init(0, 0);
00711 }
00712
00713 delete d->startupDialog;
00714 d->startupDialog = 0;
00715 }
00716 }
00717 else if (r==KexiStartupDialog::OpenRecentResult) {
00718
00719 const KexiProjectData *data = d->startupDialog->selectedProjectData();
00720 if (data) {
00721
00722
00723 }
00725 return data!=0;
00726 }
00727
00728 if (!m_projectData)
00729 return true;
00730 }
00731
00732 if (m_projectData && (openExisting || (createDB && alsoOpenDB))) {
00733 m_projectData->setReadOnly( readOnly );
00734 m_action = OpenProject;
00735 }
00736
00737
00738
00739 return true;
00740 }
00741
00742 tristate KexiStartupHandler::detectActionForFile(
00743 KexiStartupData::Import& detectedImportAction, QString& detectedDriverName,
00744 const QString& _suggestedDriverName, const QString &dbFileName, QWidget *parent, int options )
00745 {
00746 detectedImportAction = KexiStartupData::Import();
00747 QString suggestedDriverName(_suggestedDriverName);
00748 detectedDriverName = QString::null;
00749 QFileInfo finfo(dbFileName);
00750 if (dbFileName.isEmpty() || !finfo.isReadable()) {
00751 if (!(options & SkipMessages))
00752 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00753 +i18n("<p>The file <nobr>\"%1\"</nobr> does not exist or is not readable.</p>")
00754 .arg(QDir::convertSeparators(dbFileName))
00755 +i18n("Check the file's permissions and whether it is already opened "
00756 "and locked by another application."));
00757 return false;
00758 }
00759
00760 KMimeType::Ptr ptr;
00761 QString mimename;
00762
00763 const bool thisIsShortcut = (options & ThisIsAShortcutToAProjectFile)
00764 || (options & ThisIsAShortcutToAConnectionData);
00765
00766 if ((options & ThisIsAProjectFile) || !thisIsShortcut) {
00767
00768 ptr = KMimeType::findByFileContent(dbFileName);
00769 mimename = ptr.data()->name();
00770 kdDebug() << "KexiStartupHandler::detectActionForFile(): found mime is: "
00771 << mimename << endl;
00772 if (mimename.isEmpty() || mimename=="application/octet-stream" || mimename=="text/plain") {
00773
00774 ptr = KMimeType::findByURL(dbFileName);
00775 mimename = ptr.data()->name();
00776 }
00777 }
00778 if (mimename.isEmpty() || mimename=="application/octet-stream") {
00779
00780 QFile f(dbFileName);
00781 if (!f.open(IO_ReadOnly)) {
00782
00783 if (!(options & SkipMessages))
00784 KMessageBox::sorry(parent, i18n("<p>Could not open project.</p>")
00785 +i18n("<p>The file <nobr>\"%1\"</nobr> is not readable.</p>")
00786 .arg(QDir::convertSeparators(dbFileName))
00787 +i18n("Check the file's permissions and whether it is already opened "
00788 "and locked by another application."));
00789 return false;
00790 }
00791 }
00792 if ((options & ThisIsAShortcutToAProjectFile) || mimename=="application/x-kexiproject-shortcut") {
00793 detectedDriverName = "shortcut";
00794 return true;
00795 }
00796
00797 if ((options & ThisIsAShortcutToAConnectionData) || mimename=="application/x-kexi-connectiondata") {
00798 detectedDriverName = "connection";
00799 return true;
00800 }
00801
00804 if (ptr.data()) {
00805 if (mimename=="application/x-msaccess") {
00806 if ((options & SkipMessages) || KMessageBox::Yes != KMessageBox::questionYesNo(
00807 parent, i18n("\"%1\" is an external file of type:\n\"%2\".\n"
00808 "Do you want to import the file as a Kexi project?")
00809 .arg(QDir::convertSeparators(dbFileName)).arg(ptr.data()->comment()),
00810 i18n("Open External File"), KGuiItem(i18n("Import...")), KStdGuiItem::cancel() ) )
00811 {
00812 return cancelled;
00813 }
00814 detectedImportAction.mimeType = mimename;
00815 detectedImportAction.fileName = dbFileName;
00816 return true;
00817 }
00818 }
00819
00820 if (!finfo.isWritable()) {
00822 }
00823
00824
00825 QString tmpDriverName = Kexi::driverManager().lookupByMime(mimename).latin1();
00826
00827 bool useDetectedDriver = suggestedDriverName.isEmpty() || suggestedDriverName.lower()==detectedDriverName.lower();
00828 if (!useDetectedDriver) {
00829 int res = KMessageBox::Yes;
00830 if (!(options & SkipMessages))
00831 res = KMessageBox::warningYesNoCancel(parent, i18n(
00832 "The project file \"%1\" is recognized as compatible with \"%2\" database driver, "
00833 "while you have asked for \"%3\" database driver to be used.\n"
00834 "Do you want to use \"%4\" database driver?")
00835 .arg(QDir::convertSeparators(dbFileName))
00836 .arg(tmpDriverName).arg(suggestedDriverName).arg(tmpDriverName));
00837 if (KMessageBox::Yes == res)
00838 useDetectedDriver = true;
00839 else if (KMessageBox::Cancel == res)
00840 return cancelled;
00841 }
00842 if (useDetectedDriver) {
00843 detectedDriverName = tmpDriverName;
00844 }
00845 else {
00846 detectedDriverName = suggestedDriverName;
00847 }
00848
00849
00850 const QString newFileFormat = "SQLite3";
00851 if (!(options & DontConvert || options & SkipMessages)
00852 && detectedDriverName.lower()=="sqlite2" && detectedDriverName.lower()!=suggestedDriverName.lower()
00853 && KMessageBox::Yes == KMessageBox::questionYesNo(parent, i18n(
00854 "Previous version of database file format (\"%1\") is detected in the \"%2\" "
00855 "project file.\nDo you want to convert the project to a new \"%3\" format (recommended)?")
00856 .arg(detectedDriverName).arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat)) )
00857 {
00858
00859 SQLite2ToSQLite3Migration migr( finfo.absFilePath() );
00860 tristate res = migr.run();
00861
00862 if (!res) {
00863
00864 KMessageBox::sorry(parent, i18n(
00865 "Failed to convert project file \"%1\" to a new \"%2\" format.\n"
00866 "The file format remains unchanged.")
00867 .arg(QDir::convertSeparators(dbFileName)).arg(newFileFormat) );
00868
00869 }
00870 if (res==true)
00871 detectedDriverName = newFileFormat;
00872 }
00873
00874 if (detectedDriverName.isEmpty()) {
00875 QString possibleProblemsInfoMsg( Kexi::driverManager().possibleProblemsInfoMsg() );
00876 if (!possibleProblemsInfoMsg.isEmpty()) {
00877 possibleProblemsInfoMsg.prepend(QString::fromLatin1("<p>")+i18n("Possible problems:"));
00878 possibleProblemsInfoMsg += QString::fromLatin1("</p>");
00879 }
00880 if (!(options & SkipMessages))
00881 KMessageBox::detailedSorry(parent,
00882 i18n( "The file \"%1\" is not recognized as being supported by Kexi.")
00883 .arg(QDir::convertSeparators(dbFileName)),
00884 QString::fromLatin1("<p>")
00885 +i18n("Database driver for this file type not found.\nDetected MIME type: %1")
00886 .arg(mimename)
00887 +(ptr.data()->comment().isEmpty()
00888 ? QString::fromLatin1(".") : QString::fromLatin1(" (%1).").arg(ptr.data()->comment()))
00889 +QString::fromLatin1("</p>")
00890 +possibleProblemsInfoMsg);
00891 return false;
00892 }
00893 return true;
00894 }
00895
00896 KexiProjectData*
00897 KexiStartupHandler::selectProject(KexiDB::ConnectionData *cdata, bool& cancelled, QWidget *parent)
00898 {
00899 clearStatus();
00900 cancelled = false;
00901 if (!cdata)
00902 return 0;
00903 if (!cdata->savePassword && cdata->password.isEmpty()) {
00904 if (!d->passwordDialog)
00905 d->passwordDialog = new KexiDBPasswordDialog(0, *cdata, false);
00906 const int ret = d->passwordDialog->exec();
00907 if (d->passwordDialog->showConnectionDetailsRequested() || ret == QDialog::Accepted) {
00908
00909 } else {
00910 cancelled = true;
00911 return 0;
00912 }
00913 }
00914 KexiProjectData* projectData = 0;
00915
00916 KexiProjectSelectorDialog prjdlg( parent, "prjdlg", cdata, true, false );
00917 if (!prjdlg.projectSet() || prjdlg.projectSet()->error()) {
00918 KexiGUIMessageHandler msgh;
00919 if (prjdlg.projectSet())
00920 msgh.showErrorMessage(prjdlg.projectSet(),
00921 i18n("Could not load list of available projects for <b>%1</b> database server.")
00922 .arg(cdata->serverInfoString(true)));
00923 else
00924 msgh.showErrorMessage(
00925 i18n("Could not load list of available projects for <b>%1</b> database server.")
00926 .arg(cdata->serverInfoString(true)));
00927
00928
00929 return 0;
00930 }
00931 if (prjdlg.exec()!=QDialog::Accepted) {
00932 cancelled = true;
00933 return 0;
00934 }
00935 if (prjdlg.selectedProjectData()) {
00936
00937 projectData = new KexiProjectData(*prjdlg.selectedProjectData());
00938 }
00939 return projectData;
00940 }
00941
00942 void KexiStartupHandler::slotSaveShortcutFileChanges()
00943 {
00944 bool ok = true;
00945 if (d->shortcutFile)
00946 ok = d->shortcutFile->saveProjectData(d->connDialog->currentProjectData(),
00947 d->connDialog->savePasswordOptionSelected(),
00948 &d->shortcutFileGroupKey );
00949 else if (d->connShortcutFile)
00950 ok = d->connShortcutFile->saveConnectionData(
00951 *d->connDialog->currentProjectData().connectionData(),
00952 d->connDialog->savePasswordOptionSelected(),
00953 &d->shortcutFileGroupKey );
00954
00955 if (!ok) {
00956 KMessageBox::sorry(0, i18n("Failed saving connection data to\n\"%1\" file.")
00957 .arg(QDir::convertSeparators(d->shortcutFile->fileName())));
00958 }
00959 }
00960
00961
00962
00963
00964
00965
00966
00967 #include "KexiStartup.moc"