mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user