Qalculate! – TDE frontend for the ultimate desktop calculator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
qalculate-tde/src/main.cpp

307 lines
10 KiB

/***************************************************************************
* Copyright (C) 2005-2006 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "kqalculate.h"
#include "preferences.h"
#include <string>
#include <twin.h>
#include <kuniqueapplication.h>
#include <tdeaboutdata.h>
#include <tdecmdlineargs.h>
#include <tdelocale.h>
#include <unistd.h>
#include <tqtextcodec.h>
#include <tqobject.h>
#include <tdemessagebox.h>
#include <tqtimer.h>
#include <klineedit.h>
#include <tqtooltip.h>
#include <tqclipboard.h>
#include "qalculateexpressionedit.h"
#include "qalculateresultdisplay.h"
#include "qalculate_tde_utils.h"
static const char description[] = I18N_NOOP("A powerful and easy to use desktop calculator");
static const char version[] = VERSION;
static TDECmdLineOptions options[] = {
{"c", 0, 0},
{"clipboard", I18N_NOOP("Calculate X11-clipboard content (selected text)"), 0},
{"+[Expression]", I18N_NOOP( "Initial expression to calculate" ), 0},
TDECmdLineLastOption
};
extern KnownVariable *vans[5];
extern MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct;
extern TQString result_text, result_history_text, parsed_text;
extern TQWidget *expressionWidget, *resultWidget, *statusWidget_l;
extern TQWidget *topWidget;
extern KQalculate *mainWin;
extern bool load_global_defs, fetch_exchange_rates_at_startup, first_time, first_qalculate_run;
extern bool b_busy;
extern bool canplot;
extern bool close_to_systray;
extern FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w;
extern pthread_t view_thread, command_thread;
extern pthread_attr_t view_thread_attr, command_thread_attr;
extern bool command_thread_started;
extern TQValueVector<TQString> recent_functions_pre;
extern TQValueVector<TQString> recent_variables_pre;
extern TQValueVector<TQString> recent_units_pre;
TQTimer *error_timer;
void create_qalculate_window(KUniqueApplication *parent) {
TQTextCodec::setCodecForCStrings(TQTextCodec::codecForName("utf8"));
b_busy = false;
new Calculator();
if(TDEGlobal::locale()->decimalSymbol() == ",") CALCULATOR->useDecimalComma();
CALCULATOR->place_currency_code_before = TDEGlobal::locale()->positivePrefixCurrencySymbol();
//load application specific preferences
load_preferences();
mstruct = new MathStructure();
parsed_mstruct = new MathStructure();
parsed_tostruct = new MathStructure();
parsed_tostruct->setUndefined();
matrix_mstruct = new MathStructure();
canplot = CALCULATOR->canPlot();
mainWin = new KQalculate(parent);
topWidget = mainWin;
expressionWidget = (TQWidget*) mainWin->expressionEdit;
resultWidget = (TQWidget*) mainWin->resultLabel;
statusWidget_l = (TQWidget*) mainWin->statusLabel_l;
}
TQString parse_expression_arguments(TDECmdLineArgs *args) {
TQString calc_arg;
if(args->isSet("clipboard")) {
calc_arg = tqApp->clipboard()->text(TQClipboard::Selection);
if(calc_arg.isEmpty()) {
calc_arg = tqApp->clipboard()->text(TQClipboard::Clipboard);
}
} else {
for(int i = 0; i < args->count(); i++) {
if(i > 0) {
calc_arg += " ";
}
calc_arg += args->arg(i);
}
}
return calc_arg;
}
void start_qalculate() {
TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
TQString calc_arg = parse_expression_arguments(args);
args->clear();
if(!calc_arg.isEmpty()) {
mainWin->expressionEdit->setText(calc_arg);
} else if(first_time) {
mainWin->resultLabel->setText(i18n("Enter a mathematical expression above.<br>Ex. 5 + 2 / 3"));
} else {
mainWin->resultLabel->setText("<div align=\"right\"><font size=2>&nbsp;<br></font><font size=6>= 0</font></div>");
}
tqApp->processEvents();
//exchange rates
if(first_qalculate_run) {
if(KMessageBox::questionYesNo(mainWin, i18n("You need to download exchange rates to be able to convert between different currencies. You can later get current exchange rates by selecting \"Update Exchange Rates\" under the File menu.\n\nDo you want to fetch exchange rates now from the Internet?"), i18n("Update exchange rates?")) == KMessageBox::Yes) {
tqApp->processEvents();
mainWin->fetch_exchange_rates(5);
}
tqApp->processEvents();
} else if(fetch_exchange_rates_at_startup) {
mainWin->fetch_exchange_rates(5);
tqApp->processEvents();
}
CALCULATOR->loadExchangeRates();
std::string ans_str = i18n("ans").ascii();
vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str, m_undefined, i18n("Last Answer").ascii(), false));
vans[0]->addName(i18n("answer").ascii());
vans[0]->addName(ans_str + "1");
vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "2", m_undefined, i18n("Answer 2").ascii(), false));
vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "3", m_undefined, i18n("Answer 3").ascii(), false));
vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "4", m_undefined, i18n("Answer 4").ascii(), false));
vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "5", m_undefined, i18n("Answer 5").ascii(), false));
//load global definitions
if(load_global_defs && !CALCULATOR->loadGlobalDefinitions()) {
KMessageBox::error(mainWin, i18n("Failed to load global definitions!"), i18n("Error"));
tqApp->processEvents();
}
//load local definitions
CALCULATOR->loadLocalDefinitions();
//check for calculation errros regularly
error_timer = new TQTimer(mainWin);
TQObject::connect(error_timer, SIGNAL(timeout()), mainWin, SLOT(onErrorTimeout()));
generate_units_tree_struct();
generate_functions_tree_struct();
generate_variables_tree_struct();
mainWin->create_fmenu();
mainWin->create_vmenu();
mainWin->create_umenu();
mainWin->create_toumenu();
mainWin->create_setpmenu();
for(int i = ((int) recent_functions_pre.size()) - 1; i >= 0; i--) {
mainWin->function_inserted(CALCULATOR->getActiveFunction(recent_functions_pre[i].ascii()));
}
for(int i = ((int) recent_variables_pre.size()) - 1; i >= 0; i--) {
mainWin->variable_inserted(CALCULATOR->getActiveVariable(recent_variables_pre[i].ascii()));
}
for(int i = ((int) recent_units_pre.size()) - 1; i >= 0; i--) {
Unit *u = CALCULATOR->getActiveUnit(recent_units_pre[i].ascii());
if(!u) u = CALCULATOR->getCompositeUnit(recent_units_pre[i].ascii());
mainWin->unit_inserted(u);
}
mainWin->update_completion();
int pipe_wr[] = {0, 0};
pipe(pipe_wr);
view_pipe_r = fdopen(pipe_wr[0], "r");
view_pipe_w = fdopen(pipe_wr[1], "w");
pthread_attr_init(&view_thread_attr);
pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r);
int pipe_wr2[] = {0, 0};
pipe(pipe_wr2);
command_pipe_r = fdopen(pipe_wr2[0], "r");
command_pipe_w = fdopen(pipe_wr2[1], "w");
pthread_attr_init(&command_thread_attr);
command_thread_started = false;
TQObject::connect(tqApp, SIGNAL(lastWindowClosed()), tqApp, SLOT(quit()));
TQObject::connect(tqApp, SIGNAL(aboutToQuit()), mainWin, SLOT(aboutToQuit()));
error_timer->start(100);
if(!calc_arg.isEmpty()) {
mainWin->execute_expression();
}
}
class QalculateApp : public KUniqueApplication {
public:
bool started;
QalculateApp() {started = false;}
virtual ~QalculateApp() {}
int newInstance() {
if(mainWin && started) {
TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
TQString calc_arg = parse_expression_arguments(args);
args->clear();
#if TDE_VERSION_MAJOR < 4 && TDE_VERSION_MINOR < 2
KWin::Info info = KWin::info(mainWin->winId());
KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
mainWin->move(info.geometry.topLeft());
#else
KWin::WindowInfo info = KWin::windowInfo(mainWin->winId(), (unsigned long) NET::WMGeometry);
KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
mainWin->move(info.geometry().topLeft());
#endif
mainWin->setShown(true);
mainWin->show();
mainWin->raise();
#if TDE_VERSION_MAJOR < 4 && TDE_VERSION_MINOR < 2
KWin::setActiveWindow(mainWin->winId());
#else
KWin::activateWindow(mainWin->winId());
#endif
if(!calc_arg.isEmpty()) {
mainWin->expressionEdit->setText(calc_arg);
mainWin->execute_expression();
}
return 0;
} else {
if(isRestored() && TDEMainWindow::canBeRestored(1)) {
create_qalculate_window(this);
setMainWidget(mainWin);
mainWin->restore(1, false);
start_qalculate();
} else {
create_qalculate_window(this);
setMainWidget(mainWin);
mainWin->show();
start_qalculate();
}
started = true;
return KUniqueApplication::newInstance();
}
started = true;
return 0;
}
};
int main(int argc, char **argv) {
mainWin = NULL;
TDEAboutData about(PACKAGE, I18N_NOOP("Qalculate!"), version, description, TDEAboutData::License_GPL, "(C) 2005-2006 Niklas Knutsson", 0, "http://qalculate.sourceforge.net/", "nique769@users.sourceforge.net");
about.addAuthor("Niklas Knutsson", 0, "nq@altern.org");
TDECmdLineArgs::init(argc, argv, &about);
TDECmdLineArgs::addCmdLineOptions(options);
KUniqueApplication::addCmdLineOptions();
if(!QalculateApp::start()) {
return 0;
}
QalculateApp app;
return app.exec();
}