More C++/Qt4 frontend work.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18782 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming
2010-03-02 20:22:23 +00:00
parent ed75831a88
commit 68b8878ab5
2 changed files with 275 additions and 23 deletions

View File

@@ -41,6 +41,7 @@ extern "C"
#include "core-utils/gnc-main.h"
#include "engine/gnc-session.h"
#include "engine/engine-helpers.h"
#include "engine/cashobjects.h"
#include "swig-runtime.h"
#include "gnc-backend-xml.h"
@@ -169,14 +170,20 @@ main(int argc, char ** argv)
gnc::gnc_log_init();
qof_init();
gnc_module_system_init();
cashobjects_register();
// For the XML file backend
qof_backend_module_init();
// From here on the new C++ code
QApplication app(argc, argv);
gnc::MainWindow mainWin;
mainWin.show();
return app.exec();
int r = app.exec();
qof_close();
return r;
}

View File

@@ -3,9 +3,24 @@
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
// gnucash includes
#include "config.h"
extern "C" {
#include <glib/gi18n.h>
#include "qof.h"
#include "engine/gnc-session.h"
#include "engine/gnc-hooks.h"
#include "engine/gnc-filepath-utils.h"
#include "engine/Account.h"
#include "engine/TransLog.h"
}
namespace gnc
{
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_GUI;
MainWindow::MainWindow()
: ui(new Ui::MainWindow)
{
@@ -36,6 +51,20 @@ void MainWindow::closeEvent(QCloseEvent *event)
{
writeSettings();
event->accept();
QofSession *session = gnc_get_current_session ();
/* disable events; otherwise the mass deletion of accounts and
* transactions during shutdown would cause massive redraws */
qof_event_suspend ();
qof_session_call_close_hooks(session);
gnc_hook_run(HOOK_BOOK_CLOSED, session);
gnc_clear_current_session();
gnc_get_current_session ();
qof_event_resume ();
}
else
{
@@ -43,15 +72,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
}
}
void MainWindow::newFile()
{
if (maybeSave())
{
ui->textEdit->clear();
setCurrentFile("");
}
}
void MainWindow::open()
{
if (maybeSave())
@@ -176,21 +196,171 @@ bool MainWindow::maybeSave()
return true;
}
// ////////////////////////////////////////////////////////////
static void
gnc_book_opened (void)
{
gnc_hook_run(HOOK_BOOK_OPENED, gnc_get_current_session());
}
void MainWindow::newFile()
{
if (maybeSave())
{
if (gnc_current_session_exist()) {
QofSession *session = gnc_get_current_session ();
/* close any ongoing file sessions, and free the accounts.
* disable events so we don't get spammed by redraws. */
qof_event_suspend ();
qof_session_call_close_hooks(session);
gnc_hook_run(HOOK_BOOK_CLOSED, session);
gnc_clear_current_session();
qof_event_resume ();
}
/* start a new book */
gnc_get_current_session ();
gnc_hook_run(HOOK_NEW_BOOK, NULL);
//gnc_gui_refresh_all ();
/* Call this after re-enabling events. */
gnc_book_opened ();
setCurrentFile("");
}
}
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text))
if (fileName.isEmpty())
return;
// copied from gnc_post_file_open, gnome-utils/gnc-file.c
/* disable events while moving over to the new set of accounts;
* the mass deletion of accounts and transactions during
* switchover would otherwise cause excessive redraws. */
qof_event_suspend ();
/* Change the mouse to a busy cursor */
//gnc_set_busy_cursor (NULL, TRUE);
/* -------------- BEGIN CORE SESSION CODE ------------- */
/* -- this code is almost identical in FileOpen and FileSaveAs -- */
QofSession *current_session = gnc_get_current_session();
qof_session_call_close_hooks(current_session);
gnc_hook_run(HOOK_BOOK_CLOSED, current_session);
gnc_clear_current_session();
/* load the accounts from the users datafile */
/* but first, check to make sure we've got a session going. */
QofSession *new_session = qof_session_new ();
bool uh_oh = false;
QByteArray newfile = fileName.toUtf8();
qof_session_begin (new_session, newfile, FALSE, FALSE);
QofBackendError io_err = qof_session_get_error (new_session);
/* if file appears to be locked, ask the user ... */
if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
{
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
QString fmt1 = tr("GnuCash could not obtain the lock for %1.").arg(fileName);
QString fmt2 =
((ERR_BACKEND_LOCKED == io_err)
? tr("That database may be in use by another user, "
"in which case you should not open the database. "
"What would you like to do? Open anyway? FIXME")
: tr("That database may be on a read-only file system, "
"or you may not have write permission for the directory. "
"If you proceed you may not be able to save any changes. "
"What would you like to do? Open anyway? FIXME"));
if (QMessageBox::question(this, fmt1, fmt2)
== QMessageBox::Ok)
{
/* user told us to ignore locks. So ignore them. */
qof_session_begin (new_session, newfile, TRUE, FALSE);
}
else
{
/* Can't use the given file, so just create a new
* database so that the user will get a window that
* they can click "Exit" on.
*/
newFile();
}
}
/* if the database doesn't exist, ask the user ... */
else if ((ERR_BACKEND_NO_SUCH_DB == io_err) ||
(ERR_SQL_DB_TOO_OLD == io_err))
{
if (QMessageBox::question(this, tr("Create New File?"),
tr("The file %1 does not exist. Do you want to create it?").arg(fileName))
== QMessageBox::Ok)
{
/* user told us to create a new database. Do it. */
qof_session_begin (new_session, newfile, FALSE, TRUE);
}
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
ui->textEdit->setPlainText(in.readAll());
/* Check for errors again, since above may have cleared the lock.
* If its still locked, still, doesn't exist, still too old, then
* don't bother with the message, just die. */
io_err = qof_session_get_error (new_session);
if ((ERR_BACKEND_LOCKED == io_err) ||
(ERR_BACKEND_READONLY == io_err) ||
(ERR_BACKEND_NO_SUCH_DB == io_err) ||
(ERR_SQL_DB_TOO_OLD == io_err))
{
uh_oh = true;
}
else
{
uh_oh = !(QMessageBox::question(this, tr("Open anyway?"),
tr("The file %1 has some errors (FIXME). Open anyway?").arg(fileName))
== QMessageBox::Ok);
}
if (!uh_oh)
{
::Account *new_root;
char * logpath = xaccResolveFilePath(newfile);
PINFO ("logpath=%s", logpath ? logpath : "(null)");
xaccLogSetBaseName (logpath);
xaccLogDisable();
statusBar()->showMessage(tr("Loading user data..."), 2000);
qof_session_load (new_session, NULL);
xaccLogEnable();
/* check for i/o error, put up appropriate error dialog */
io_err = qof_session_get_error (new_session);
uh_oh = !(QMessageBox::question(this, tr("Error on Open"),
tr("There was an error opening the file %1. FIXME").arg(fileName))
== QMessageBox::Ok);
new_root = gnc_book_get_root_account (qof_session_get_book (new_session));
if (uh_oh) new_root = NULL;
}
/* if we got to here, then we've successfully gotten a new session */
/* close up the old file session (if any) */
gnc_set_current_session(new_session);
qof_event_resume ();
/* Call this after re-enabling events. */
gnc_book_opened ();
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
@@ -200,7 +370,7 @@ void MainWindow::loadFile(const QString &fileName)
bool MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text))
if (!file.open(QFile::WriteOnly))
{
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
@@ -208,10 +378,85 @@ bool MainWindow::saveFile(const QString &fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
file.close();
QApplication::setOverrideCursor(Qt::WaitCursor);
out << ui->textEdit->toPlainText();
QofSession *session = gnc_get_current_session ();
/* Make sure all of the data from the old file is loaded */
qof_session_ensure_all_data_loaded(session);
/* -- this session code is NOT identical in FileOpen and FileSaveAs -- */
QByteArray newfile = fileName.toUtf8();
xaccLogSetBaseName(newfile); //FIXME: This is premature.
QofSession *new_session = qof_session_new ();
qof_session_begin (new_session, newfile, FALSE, FALSE);
QofBackendError io_err = qof_session_get_error (new_session);
/* if file appears to be locked, ask the user ... */
if (ERR_BACKEND_LOCKED == io_err || ERR_BACKEND_READONLY == io_err)
{
if (QMessageBox::question(this, tr("Ignore Lock?"),
tr("The file %1 is locked. Should we ignore the lock?").arg(fileName))
== QMessageBox::Ok)
{
/* user told us to ignore locks. So ignore them. */
qof_session_begin (new_session, newfile, TRUE, FALSE);
}
}
/* if the database doesn't exist, ask the user ... */
else if ((ERR_FILEIO_FILE_NOT_FOUND == io_err) ||
(ERR_BACKEND_NO_SUCH_DB == io_err) ||
(ERR_SQL_DB_TOO_OLD == io_err))
{
if (QMessageBox::question(this, tr("Create New File?"),
tr("The file %1 does not exist. Should it be created?").arg(fileName)))
{
/* user told us to create a new database. Do it. */
qof_session_begin (new_session, newfile, FALSE, TRUE);
}
}
/* check again for session errors (since above dialog may have
* cleared a file lock & moved things forward some more)
* This time, errors will be fatal.
*/
io_err = qof_session_get_error (new_session);
if (ERR_BACKEND_NO_ERR != io_err)
{
QMessageBox::critical(this, tr("Still in Error"),
tr("The file %1 still cannot be written. FIXME").arg(fileName));
xaccLogDisable();
qof_session_destroy (new_session);
xaccLogEnable();
return false;
}
/* Prevent race condition between swapping the contents of the two
* sessions, and actually installing the new session as the current
* one. Any event callbacks that occur in this interval will have
* problems if they check for the current book. */
qof_event_suspend();
/* if we got to here, then we've successfully gotten a new session */
/* close up the old file session (if any) */
qof_session_swap_data (session, new_session);
gnc_clear_current_session();
session = NULL;
/* XXX At this point, we should really mark the data in the new session
* as being 'dirty', since we haven't saved it at all under the new
* session. But I'm lazy...
*/
gnc_set_current_session(new_session);
qof_event_resume();
/* --------------- END CORE SESSION CODE -------------- */
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);