initial import

git-svn-id: svn://ttmath.org/publicrep/ttcalc/trunk@2 e52654a7-88a9-db11-a3e9-0013d4bc506e
0.8.x
Tomasz Sowa 2007-01-22 11:12:01 +00:00
commit 368711c76c
28 changed files with 5647 additions and 0 deletions

2
CHANGELOG Normal file
View File

@ -0,0 +1,2 @@

28
COPYRIGHT Normal file
View File

@ -0,0 +1,28 @@
Copyright (c) 2006-2007, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name Tomasz Sowa nor the names of contributors to this
project may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

17
TODO Normal file
View File

@ -0,0 +1,17 @@
TODO TTCalc
===========
* increase the input edit
* when the program should be run as the maximalized window, the window is only
resizing horizontly
* doesn't set 'always on top' if it was in the configuration file
* add the button 'error' which shows us where is incorrect character (in input edit)
* add the test when program is being starded which checks if the coordinates of the
main window actually pointing
at the valid area (for example when someone take his configuration file into a
new computer)
* add some physical constants
* make the help
* the focus (from tab key) doesn't go from tabs into their controls
* when compiling under Cygwin the program has a problem with line-ends in
the configuration file (/r/n)

BIN
res/abacus_01.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
res/icon01.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

43
src/Makefile Normal file
View File

@ -0,0 +1,43 @@
CC = g++
o = resource.o calculation.o functions.o iniparser.o languages.o mainwindow.o parsermanager.o programresources.o tabs.o variables.o winmain.o
CFLAGS = -Wall -pedantic -s -O3 -mwindows -mthreads -I../../../ttmath
name = ttcalc.exe
dir_output = ../../output
.SUFFIXES: .cpp .o
.cpp.o:
$(CC) -c $(CFLAGS) $<
all: ttcalc
ttcalc: $(o)
$(CC) -o $(dir_output)/$(name) $(CFLAGS) $(o) -lcomctl32
resource.o: resource.rc
windres resource.rc resource.o
calculation.o: calculation.cpp compileconfig.h parsermanager.h resource.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
functions.o: functions.cpp compileconfig.h tabs.h resource.h messages.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
iniparser.o: iniparser.cpp compileconfig.h iniparser.h
languages.o: languages.cpp compileconfig.h languages.h
mainwindow.o: mainwindow.cpp compileconfig.h winmain.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h resource.h messages.h tabs.h
parsermanager.o: parsermanager.cpp compileconfig.h parsermanager.h resource.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
programresources.o: programresources.cpp compileconfig.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
tabs.o: tabs.cpp compileconfig.h tabs.h resource.h messages.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
variables.o: variables.cpp compileconfig.h tabs.h resource.h messages.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h
winmain.o: winmain.cpp compileconfig.h winmain.h programresources.h iniparser.h languages.h threadcontroller.h stopcalculating.h resource.h messages.h tabs.h
clean:
rm -f *.o
rm -f *.s
rm -f $(dir_output)/$(name)
rm -f $(name_cons)

56
src/calculation.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "compileconfig.h"
#include "parsermanager.h"
#include <process.h>
/*!
the function for the second thread
*/
//DWORD WINAPI CalculationsProcedure(LPVOID lpParameter)
unsigned __stdcall CalculationsProcedure(void *)
{
/*
using namespace ttmath;
Parser<Big<3,9> > parser;
parser.Parse("6");
std::string buf;
parser.stack[0].value.ToString(buf);
MessageBox(0, buf.c_str(), "", 0);
*/
ParserManager parser_manager;
parser_manager.Init();
// the main loop of calculations
while( GetPrgRes()->GetThreadController()->WaitForCalculatingAndBlockForStop() )
{
// for the first we must copy all variables which we're using
// (at this moment all calling from the main thread are stopped)
parser_manager.MakeCopyOfVariables();
// then we can set 'thread_controller' as being ready for 'stop' signal
GetPrgRes()->GetThreadController()->ReadyForStop();
// (now the main thread can call various methods for changing state)
// and finally we're cleaning the output window and parsing the input string
SetDlgItemText(GetPrgRes()->GetMainWindow(),IDC_OUTPUT_EDIT,"");
parser_manager.Parse();
// if there was a stop signal we continue the main loop without printing any values
if( GetPrgRes()->GetThreadController()->WasStopSignal() )
continue;
// at the end we're printing the result
parser_manager.PrintResult();
}
_endthreadex(0);
return 0;
}

38
src/compileconfig.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef headerfilecompileconfig
#define headerfilecompileconfig
/*!
this macro disables visual c warnings about deprecated unsafe standard functions
like fopen etc.
*/
#define _CRT_SECURE_NO_DEPRECATE
/*!
the number of build
(autoincrement by a compile script)
*/
#define TTCALC_BUILD 1
/*!
the version of the application
*/
#define TTCALC_MAJOR_VER 0
#define TTCALC_MINOR_VER 7
#define TTCALC_REVISION_VER 0
/*!
this disables a Visual C++ warning about converting int to bool
"warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)"
*/
#ifdef _MSC_VER
#pragma warning (disable : 4800)
#endif
#define _WIN32_IE 0x0501
#endif

277
src/functions.cpp Normal file
View File

@ -0,0 +1,277 @@
#include "compileconfig.h"
#include "tabs.h"
namespace TabWindowFunctions
{
namespace Functions
{
std::string caption,name,value;
int parameters;
bool adding;
BOOL CALLBACK DialogProcFunction(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static const int temporary_buffer_size = 200;
char * pchar;
char short_buffer[20];
int i;
switch(message)
{
case WM_INITDIALOG:
SetWindowText(hWnd, caption.c_str());
SetDlgItemText(hWnd, IDC_STATIC_FUNCTION_NAME, GetPrgRes()->GetLanguages()->GuiMessage(Languages::list_functions_header_1));
SetDlgItemText(hWnd, IDC_STATIC_FUNCTION_PARAM, GetPrgRes()->GetLanguages()->GuiMessage(Languages::list_functions_header_2));
SetDlgItemText(hWnd, IDC_STATIC_FUNCTION_VALUE, GetPrgRes()->GetLanguages()->GuiMessage(Languages::list_functions_header_3));
SetDlgItemText(hWnd, IDOK, GetPrgRes()->GetLanguages()->GuiMessage(Languages::button_ok));
SetDlgItemText(hWnd, IDCANCEL,GetPrgRes()->GetLanguages()->GuiMessage(Languages::button_cancel));
SetDlgItemText(hWnd,IDC_EDIT_FUNCTION_NAME, name.c_str());
SetDlgItemText(hWnd,IDC_EDIT_FUNCTION_VALUE, value.c_str());
for(i=0 ; i<10 ; ++i)
{
sprintf(short_buffer,"%u", i);
SendDlgItemMessage(hWnd,IDC_COMBO_FUNCTION_PARAM,CB_ADDSTRING,0,(LPARAM)short_buffer);
}
if( parameters < 0 )
parameters = 0;
else
if( parameters > 9 )
parameters = 9;
SendDlgItemMessage(hWnd,IDC_COMBO_FUNCTION_PARAM,CB_SETCURSEL,parameters,0);
if( adding )
{
SetFocus(GetDlgItem(hWnd,IDC_EDIT_FUNCTION_NAME));
}
else
{
EnableWindow(GetDlgItem(hWnd,IDC_EDIT_FUNCTION_NAME), false);
SetFocus(GetDlgItem(hWnd,IDC_EDIT_FUNCTION_VALUE));
}
return false;
case WM_COMMAND:
if( LOWORD(wParam) == IDOK )
{
pchar = new char[temporary_buffer_size];
GetDlgItemText(hWnd, IDC_EDIT_FUNCTION_NAME, pchar, temporary_buffer_size);
name = Variables::ChangeToSmallLetters( Variables::StripWhiteCharacters(pchar) );
GetDlgItemText(hWnd, IDC_EDIT_FUNCTION_VALUE, pchar, temporary_buffer_size);
value = Variables::ChangeToSmallLetters( Variables::StripWhiteCharacters(pchar) );
parameters = (int)SendDlgItemMessage(hWnd,IDC_COMBO_FUNCTION_PARAM,CB_GETCURSEL,0,0);
delete [] pchar;
EndDialog(hWnd,1);
}
else
if( LOWORD(wParam) == IDCANCEL )
{
EndDialog(hWnd,0);
return true;
}
break;
}
return false;
}
void AddNewItemToFunctionList(HWND list, const std::string & name, const std::string & value, int parameters)
{
LVITEM item;
char buffer[20];
item.mask = LVIF_TEXT;
item.pszText = const_cast<char*>( name.c_str() );
item.iSubItem = 0;
int id = ListView_InsertItem(list, &item);
sprintf(buffer,"%u", parameters);
ListView_SetItemText(list,id,1, buffer);
ListView_SetItemText(list,id,2,const_cast<char*>( value.c_str() ));
}
void SetNewFunctionValueIntoList(HWND list, int id)
{
ttmath::ErrorCode code;
char buffer[20];
GetPrgRes()->GetThreadController()->StopCalculating();
code = GetPrgRes()->GetFunctions()->Edit(name, value, parameters);
GetPrgRes()->GetThreadController()->StartCalculating();
if( code == ttmath::err_unknown_object )
{
// there is probably an internal error
// because we should have had this function
MessageBox( list,
GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_edit_function_unknown_function),
GetPrgRes()->GetLanguages()->GuiMessage(Languages::message_box_caption),
MB_ICONERROR);
return;
}
sprintf(buffer,"%u",parameters);
ListView_SetItemText(list,id,1,buffer);
ListView_SetItemText(list,id,2,const_cast<char*>( value.c_str() ));
}
BOOL WmTabCommand_AddFunction(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
caption = GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_add_function_caption);
name = "";
value = "";
adding = true;
parameters = 1;
if( DialogBox(GetPrgRes()->GetInstance(), MAKEINTRESOURCE(IDD_DIALOG_ADD_FUNCTION), hWnd, DialogProcFunction) )
{
HWND list = GetDlgItem(hWnd, IDC_FUNCTIONS_LIST);
ttmath::ErrorCode code;
GetPrgRes()->GetThreadController()->StopCalculating();
code = GetPrgRes()->GetFunctions()->Add(name, value, parameters);
GetPrgRes()->GetThreadController()->StartCalculating();
if( code == ttmath::err_object_exists )
{
MessageBox( hWnd,
GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_add_function_function_exists),
GetPrgRes()->GetLanguages()->GuiMessage(Languages::message_box_caption),
MB_ICONERROR);
return true;
}
AddNewItemToFunctionList(list, name, value, parameters);
}
return true;
}
/*!
(we're also using this method directly without using the main loop of messages)
(we don't define the 'lParam' parameter there)
*/
BOOL WmTabCommand_EditFunction(HWND hWnd, UINT message, WPARAM wParam, LPARAM)
{
HWND list = GetDlgItem(hWnd, IDC_FUNCTIONS_LIST);
if( ListView_GetSelectedCount(list) != 1 )
// there must be only one item selected
return true;
int id = ListView_GetSelectionMark(list);
const int buffer_size = 300;
char * buffer = new char[buffer_size];
caption = GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_edit_function_caption);
ListView_GetItemText(list,id,0,buffer, buffer_size);
name = buffer;
ListView_GetItemText(list,id,2,buffer, buffer_size);
value = buffer;
ListView_GetItemText(list,id,1,buffer, buffer_size);
parameters = atoi(buffer);
delete [] buffer;
adding = false;
if( DialogBox(GetPrgRes()->GetInstance(), MAKEINTRESOURCE(IDD_DIALOG_ADD_FUNCTION), hWnd, DialogProcFunction) )
{
SetNewFunctionValueIntoList(list, id);
}
return true;
}
BOOL WmTabCommand_DeleteFunction(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND list = GetDlgItem(hWnd, IDC_FUNCTIONS_LIST);
int items = ListView_GetSelectedCount(list);
if( items == 0 )
// there must be at least one item selected
return true;
if( items > 1 )
{
// we're showing a message to confirm deleting
if( MessageBox( hWnd,
GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_delete_function_confirm),
GetPrgRes()->GetLanguages()->GuiMessage(Languages::message_box_caption),
MB_ICONWARNING | MB_YESNO) == IDNO )
return true;
}
int id;
const int buffer_size = 300;
char * buffer = new char[buffer_size];
bool all_deleted = true;
GetPrgRes()->GetThreadController()->StopCalculating();
for( id = ListView_GetItemCount(list)-1 ; id!=-1 ; --id )
{
if( ListView_GetItemState(list, id, LVIS_SELECTED) == LVIS_SELECTED )
{
ListView_GetItemText(list,id,0,buffer,buffer_size);
if( GetPrgRes()->GetFunctions()->Delete(buffer) == ttmath::err_unknown_object )
all_deleted = false;
else
ListView_DeleteItem(list, id);
}
}
GetPrgRes()->GetThreadController()->StartCalculating();
delete [] buffer;
if( !all_deleted )
// there are some items which we've not deleted
// probably an internal error
MessageBox( hWnd,
GetPrgRes()->GetLanguages()->GuiMessage(Languages::dialog_box_function_not_all_deleted),
GetPrgRes()->GetLanguages()->GuiMessage(Languages::message_box_caption),
MB_ICONERROR);
return true;
}
} // namespace
} // namespace

397
src/iniparser.cpp Normal file
View File

@ -0,0 +1,397 @@
#include "compileconfig.h"
#include "iniparser.h"
IniParser::IniParser()
{
strip_white_characters_from_value = true;
convert_value_to_small_letters = true;
}
void IniParser::Associate(const char * pattern, std::string * result)
{
table.insert( std::make_pair(std::string(pattern), result) );
}
void IniParser::Associate(const std::string & pattern, std::string * result)
{
table.insert( std::make_pair(pattern, result) );
}
void IniParser::Associate(const char * pattern, std::map<std::string, std::string> * result)
{
table_whole_section.insert( std::make_pair(std::string(pattern), result) );
}
void IniParser::Associate(const std::string & pattern, std::map<std::string, std::string> * result)
{
table_whole_section.insert( std::make_pair(pattern, result) );
}
void IniParser::Clear()
{
table.clear();
table_whole_section.clear();
}
IniParser::Error IniParser::ReadFromFile(const char * path)
{
file.open(path);
if(!file)
return err_cant_open_file;
Error err = Read();
return err;
}
int IniParser::GetBadLine()
{
return line;
}
IniParser::Error IniParser::Read()
{
std::string section, pattern, value;
Error err;
line = 1;
do
{
err = ReadSection(section);
if( err != err_ok )
break;
err = ReadExpression(pattern, value);
while( err == err_ok )
{
if( strip_white_characters_from_value )
StripWhiteCharacters(value);
CheckAndSet( section, pattern, value );
err = ReadExpression(pattern, value);
}
}
while( err == err_is_section );
if( err == err_file_end )
err = err_ok;
return err;
}
IniParser::Error IniParser::ReadSection(std::string & section)
{
section.erase();
int c = SkipCommentaryAndEmptyLines();
if( c == EOF )
return err_file_end;
if( c != '[' )
{
// this line is not for a section (empty section?)
ReturnCharacter(c);
return err_ok;
}
while( IsSectionCharacter( (c = ReadCharacter()) ) )
section += LowerCase(c);
if( c != ']' )
{
ReturnCharacter(c);
return err_incorrect_character;
}
return err_ok;
}
int IniParser::SkipCommentaryAndEmptyLines()
{
int c;
do
{
SkipWhiteCharacters();
c = ReadCharacter();
if( c == '#' )
SkipLine();
else
if( c == 10 )
c='#';
}
while( c == '#' );
return c;
}
/*
IniParser::Error IniParser::CheckEndOfLine()
{
SkipWhiteCharacters();
int c = ReadCharacter();
if( c == EOF )
return err_file_end;
if( c != 10 )
{
ReturnCharacter(c);
return err_incorrect_character;
}
return err_ok;
}
*/
IniParser::Error IniParser::ReadExpression(std::string & pattern, std::string & value)
{
pattern.erase();
value.erase();
int c = SkipCommentaryAndEmptyLines();
if( c == EOF )
return err_file_end;
if( c == '[' )
{
ReturnCharacter(c);
return err_is_section;
}
while( IsPatternCharacter(c) )
{
pattern += LowerCase(c);
c = ReadCharacter();
}
if( IsWhiteCharacter(c) )
{
SkipWhiteCharacters();
c = ReadCharacter();
}
if( c != '=' )
{
ReturnCharacter(c);
return err_incorrect_character;
}
SkipWhiteCharacters();
while( IsValueCharacter( (c = ReadCharacter()) ) )
if( convert_value_to_small_letters )
value += LowerCase(c);
else
value += c;
ReturnCharacter(c);
//return CheckEndOfLine();
return err_ok;
}
void IniParser::CheckAndSet(const std::string & section, const std::string & pattern, const std::string & value)
{
TableWholeSection::iterator iw = table_whole_section.find( section );
if( iw != table_whole_section.end() )
{
(*iw->second).insert( std::make_pair( pattern, value ) );
return;
}
Table::iterator i = table.find( section + '|' + pattern );
if( i == table.end() )
return;
*i->second = value;
}
bool IniParser::IsWhiteCharacter(int c)
{
// 13 is in 'dos and windows' systems at the end of a text file (13 and 10 exactly)
if( c==' ' || c=='\t' || c==13 )
return true;
return false;
}
void IniParser::SkipWhiteCharacters()
{
int c;
while( IsWhiteCharacter( (c=ReadCharacter()) ) );
ReturnCharacter(c);
}
int IniParser::ReadCharacter()
{
int c = file.get();
if( !file )
c = EOF;
else
if( c == 10 )
++line;
return c;
}
void IniParser::ReturnCharacter(int c)
{
file.unget();
if( c == 10 )
--line;
}
bool IniParser::IsSectionCharacter(int c)
{
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9') ||
c=='_' || c=='.' )
return true;
return false;
}
bool IniParser::IsPatternCharacter(int c)
{
return IsSectionCharacter(c);
}
bool IniParser::IsValueCharacter(int c)
{
if( c!=10 && c!=EOF )
return true;
return false;
}
void IniParser::SkipLine()
{
while( ReadCharacter() != 10 );
}
int IniParser::LowerCase(int c)
{
if( c>='A' && c<='Z')
return c - 'A' + 'a';
return c;
}
/*!
this function sets '*start' and '*end' to point to the middle part of the string
without any whitespaces at the end and at the beginning
'*start' will be the first correct character
'*end' will be after the last correct character
*/
void IniParser::CheckWhiteCharacters(const char * string, const char ** start, const char ** end)
{
const char * p;
// we're setting 'p' at the end of the string (at '\0' character)
for( p = string ; *p ; ++p );
if( p == string )
{
// an empty string
*start = *end = string;
return;
}
// we're looking for a last character which is different than a white character
for( --p ; p != string && (*p==' ' || *p=='\t') ; --p );
// 'end' will be after the last character
*end = p+1;
// we're looking for a first character which is different than a white character
for( p = string ; *p==' ' || *p=='\t' ; ++p );
*start = p;
}
void IniParser::StripWhiteCharacters(std::string & string)
{
const char *s, * start, * end;
s = string.c_str();
CheckWhiteCharacters(s, &start, &end);
std::string::size_type istart, iend;
istart = start - s;
iend = end - s;
string.erase(iend, string.length() - iend);
string.erase(0, istart);
}

133
src/iniparser.h Normal file
View File

@ -0,0 +1,133 @@
#ifndef headerfileiniparser
#define headerfileiniparser
/*!
\file iniparser.h
\brief A Parser witch we use for parsing 'ini' files
*/
#include <string>
#include <fstream>
#include <map>
/*!
\brief it implements the parser for reading 'ini' files
how it works?
first you have to create an object of this class
IniParser ini_parser;
then you must associate a pattern and its value which'll be set after parsing
ini_parser.Associate( "sec|pattern", &value );
where 'value' is std::string type
when the parser meet in the file following sequences:
---- file.ini -------
# some commentary
[sec]
pattern = some_values with space itd
---------------------
then the value 'some_values with space etc.' will be set into the 'value' variable,
you can use '#' as first character in a line which means the line is only a commentary,
a pattern and its value have to be in one line.
you can also read the whole section, for example:
[test]
item1 = 10
item2 = 20
item3 = 30
etc.
by using ...
*/
class IniParser
{
public:
typedef std::map<std::string, std::string> Section;
enum Error
{
err_ok = 0,
err_file_end,
err_is_section,
err_cant_open_file,
err_incorrect_character
};
IniParser();
/*!
these methods associate pattern and its value
(look at a description of this class)
*/
void Associate(const char * pattern, std::string * result);
void Associate(const std::string & pattern, std::string * result);
/*!
these methods associate pattern to the whole its section
*/
void Associate(const char * pattern, std::map<std::string, std::string> * result);
void Associate(const std::string & pattern, std::map<std::string, std::string> * result);
/*!
this method clears patterns and their values
*/
void Clear();
/*!
when the parser could not read correctly a ini file
this method returns a number of a bad line
*/
int GetBadLine();
/*!
this method attempts to read a file
if the reading was good it returns 'err_ok'
else it returns either 'err_cant_open_file' or 'err_incorrect_character'
*/
Error ReadFromFile(const char * path);
private:
typedef std::map<std::string, std::string *> Table;
typedef std::map<std::string, Section *> TableWholeSection;
Table table;
TableWholeSection table_whole_section;
std::ifstream file;
int line;
bool strip_white_characters_from_value;
bool convert_value_to_small_letters;
Error Read();
Error ReadSection(std::string & section);
int SkipCommentaryAndEmptyLines();
//Error CheckEndOfLine();
Error ReadExpression(std::string & pattern, std::string & value);
void CheckAndSet(const std::string & section, const std::string & pattern, const std::string & value);
bool IsWhiteCharacter(int c);
void SkipWhiteCharacters();
int ReadCharacter();
void ReturnCharacter(int c);
bool IsSectionCharacter(int c);
bool IsPatternCharacter(int c);
bool IsValueCharacter(int c);
void SkipLine();
int LowerCase(int c);
public:
static void CheckWhiteCharacters(const char * string, const char ** start, const char ** end);
static void StripWhiteCharacters(std::string & string);
};
#endif

355
src/languages.cpp Normal file
View File

@ -0,0 +1,355 @@
#include "compileconfig.h"
#include "languages.h"
const char * Languages::ErrorMessage(Country country, ttmath::ErrorCode code)
{
const char * unk_err = "unknown error";
if( error_messages_tab.empty() )
InitErrorMessagesTab();
unsigned int cid = static_cast<unsigned int>( country );
if( cid >= error_messages_tab.size() )
return unk_err;
std::map<ttmath::ErrorCode, std::string>::const_iterator i;
i = error_messages_tab[cid].find( code );
if( i == error_messages_tab[cid].end() )
return unk_err;
return i->second.c_str();
}
const char * Languages::ErrorMessage(ttmath::ErrorCode code)
{
return ErrorMessage(current_country, code);
}
void Languages::InsertErrorPair(ttmath::ErrorCode code, const char * message)
{
if( error_messages_tab.empty() )
return;
error_messages_tab.back().insert( std::make_pair(code, message) );
}
void Languages::InitErrorMessagesTab()
{
error_messages_tab.push_back( std::map<ttmath::ErrorCode, std::string>() );
InsertErrorPair(ttmath::err_ok,"ok");
InsertErrorPair(ttmath::err_nothing_has_read,"");
InsertErrorPair(ttmath::err_unknown_character,"Unknown character");
InsertErrorPair(ttmath::err_unexpected_final_bracket,"An unexpected final bracket");
InsertErrorPair(ttmath::err_stack_not_clear,"An unknown character has left");
InsertErrorPair(ttmath::err_unknown_variable,"An unknown variable");
InsertErrorPair(ttmath::err_division_by_zero,"Division by zero");
InsertErrorPair(ttmath::err_interrupt,"?");
InsertErrorPair(ttmath::err_overflow,"Overflow");
InsertErrorPair(ttmath::err_unknown_function,"An unknown function");
InsertErrorPair(ttmath::err_unexpected_semicolon_operator,"An unexpected semicolon operator");
InsertErrorPair(ttmath::err_improper_amount_of_arguments,"Improper amount of arguments");
InsertErrorPair(ttmath::err_improper_argument,"Improper argument");
InsertErrorPair(ttmath::err_unexpected_end,"Unexpected end");
InsertErrorPair(ttmath::err_internal_error,"An internal error");
InsertErrorPair(ttmath::err_incorrect_name,"Incorrect name of a variable or function");
InsertErrorPair(ttmath::err_incorrect_value,"Incorrect value of a variable or function");
InsertErrorPair(ttmath::err_variable_exists,"This variable already exists");
InsertErrorPair(ttmath::err_variable_loop,"There's a recurrence between variables");
InsertErrorPair(ttmath::err_functions_loop,"There's a recurrence between functions");
InsertErrorPair(ttmath::err_must_be_only_one_value,"Variables or functions must return only one value");
InsertErrorPair(ttmath::err_this_cant_be_used,"?");
// pl
error_messages_tab.push_back( std::map<ttmath::ErrorCode, std::string>() );
InsertErrorPair(ttmath::err_ok,"ok");
InsertErrorPair(ttmath::err_nothing_has_read,"");
InsertErrorPair(ttmath::err_unknown_character,"Nieznany znak");
InsertErrorPair(ttmath::err_unexpected_final_bracket,"Nieoczekiwany nawias zamykaj¹cy");
InsertErrorPair(ttmath::err_stack_not_clear,"Pozosta³ nieznany znak");
InsertErrorPair(ttmath::err_unknown_variable,"Nieznana zmienna");
InsertErrorPair(ttmath::err_division_by_zero,"Dzielenie przez zero");
InsertErrorPair(ttmath::err_interrupt,"?");
InsertErrorPair(ttmath::err_overflow,"Przekroczony zakres");
InsertErrorPair(ttmath::err_unknown_function,"Nieznana funkcja");
InsertErrorPair(ttmath::err_unexpected_semicolon_operator,"Nieoczekiwany operator 'œrednik'");
InsertErrorPair(ttmath::err_improper_amount_of_arguments,"Niew³aœciwa liczba argumentów");
InsertErrorPair(ttmath::err_improper_argument,"Niew³aœciwy argument");
InsertErrorPair(ttmath::err_unexpected_end,"Nieoczekiwany koniec");
InsertErrorPair(ttmath::err_internal_error,"B³¹d wewnêtrzny programu!");
InsertErrorPair(ttmath::err_incorrect_name,"Nieprawid³owa nazwa zmiennej lub funkcji");
InsertErrorPair(ttmath::err_incorrect_value,"Nieprawid³owa wartoœæ zmiennej lub funkcji");
InsertErrorPair(ttmath::err_variable_exists,"Ta zmienna juz istnieje");
InsertErrorPair(ttmath::err_variable_loop,"Pomiêdzy zmiennymi zachodzi wywo³anie rekurencyjne");
InsertErrorPair(ttmath::err_functions_loop,"Pomiêdzy funkcjami zachodzi wywo³anie rekurencyjne");
InsertErrorPair(ttmath::err_must_be_only_one_value,"Zmienne albo funkcje mog¹ posiadaæ (zwracaæ) tylko jedn¹ wartoœæ");
InsertErrorPair(ttmath::err_this_cant_be_used,"?");
}
// for gui messages
const char * Languages::GuiMessage(Country country, GuiMsg code)
{
const char * unk_msg = "unknown";
if( gui_messages_tab.empty() )
InitGuiMessagesTab();
unsigned int cid = static_cast<unsigned int>( country );
if( cid >= gui_messages_tab.size() )
return unk_msg;
std::map<GuiMsg, std::string>::const_iterator i;
i = gui_messages_tab[cid].find( code );
if( i == gui_messages_tab[cid].end() )
return unk_msg;
return i->second.c_str();
}
const char * Languages::GuiMessage(GuiMsg code)
{
return GuiMessage(current_country, code);
}
void Languages::InsertGuiPair(GuiMsg code, const char * message)
{
if( gui_messages_tab.empty() )
return;
gui_messages_tab.back().insert( std::make_pair(code, message) );
}
void Languages::InitGuiMessagesTab()
{
// en
gui_messages_tab.push_back( std::map<GuiMsg, std::string>() );
InsertGuiPair(button_ok,"Ok");
InsertGuiPair(button_cancel,"Cancel");
InsertGuiPair(message_box_caption,"TTCalc");
InsertGuiPair(dialog_box_add_variable_caption,"Add a new variable");
InsertGuiPair(dialog_box_edit_variable_caption,"Edit a variable");
InsertGuiPair(dialog_box_add_variable_incorrect_name,"Incorrect name of variable");
InsertGuiPair(dialog_box_add_variable_incorrect_value,"Incorrect value of variable");
InsertGuiPair(dialog_box_add_variable_variable_exists,"This variable already exists");
InsertGuiPair(dialog_box_edit_variable_unknown_variable,"There isn't this variable in my table. There's probably an internal error!");
InsertGuiPair(dialog_box_delete_variable_confirm,"Are you sure that you want to delete those variables?");
InsertGuiPair(dialog_box_variable_not_all_deleted,"There are some variables which I was not able to delete. Probably an internal error!");
InsertGuiPair(dialog_box_add_function_caption,"Add a new function");
InsertGuiPair(dialog_box_edit_function_caption,"Edit a function");
InsertGuiPair(dialog_box_add_function_function_exists,"This function already exists");
InsertGuiPair(dialog_box_edit_function_unknown_function,"There isn't this function in my table. There's probably an internal error!");
InsertGuiPair(dialog_box_delete_function_confirm,"Are you sure that you want to delete those functions?");
InsertGuiPair(dialog_box_function_not_all_deleted,"There are some functions which I was not able to delete. Probably an internal error!");
InsertGuiPair(list_variables_header_1,"Name");
InsertGuiPair(list_variables_header_2,"Value");
InsertGuiPair(list_functions_header_1,"Name");
InsertGuiPair(list_functions_header_2,"Param.");
InsertGuiPair(list_functions_header_3,"Value");
InsertGuiPair(button_add,"Add");
InsertGuiPair(button_edit,"Edit");
InsertGuiPair(button_delete,"Delete");
InsertGuiPair(button_clear,"C");
InsertGuiPair(tab_standard,"Standard");
InsertGuiPair(tab_variables,"Variables");
InsertGuiPair(tab_functions,"Functions");
InsertGuiPair(tab_precision,"Precision");
InsertGuiPair(tab_display,"Display");
InsertGuiPair(radio_precision_1,"Small - 96 bits for mantissa, 32 bits for exponent");
InsertGuiPair(radio_precision_2,"Medium - 192 bits for mantissa, 64 bits for exponent");
InsertGuiPair(radio_precision_3,"Big - 288 bits for mantissa, 96 bits for exponent");
InsertGuiPair(precision_1_info,"(+/-)6.9 e+646457021, 26 valid digits (decimal)");
InsertGuiPair(precision_2_info,"(+/-)4.3 e+2776511644261678623, 56 valid digits");
InsertGuiPair(precision_3_info,"(+/-)2.5 e+11925026709067095507636213441, 85 valid digits");
InsertGuiPair(overflow_during_printing,"Overflow during printing");
InsertGuiPair(combo_rounding_none,"None");
InsertGuiPair(combo_rounding_cut_last_digits,"Cut off last non-valid digits");
InsertGuiPair(combo_rounding_integer,"Round to the nearest integer");
InsertGuiPair(combo_rounding_to_number,"to");
InsertGuiPair(combo_rounding_after_comma,"digit(s) after comma");
InsertGuiPair(display_input, "Input");
InsertGuiPair(display_output, "Output");
InsertGuiPair(display_rounding, "Rounding");
InsertGuiPair(display_always_scientific,"Always");
InsertGuiPair(display_not_always_scientific,"When the exp is greater than:");
InsertGuiPair(display_digit, "digits");
InsertGuiPair(display_group_scientific, "Print the result as the scientific value");
InsertGuiPair(menu_view, "&View");
InsertGuiPair(menu_edit, "&Edit");
InsertGuiPair(menu_help, "&Help");
InsertGuiPair(menu_language, "&Language");
InsertGuiPair(menu_view_new_window, "&New window");
InsertGuiPair(menu_view_normal_view, "No&rmal view");
InsertGuiPair(menu_view_compact_view, "C&ompact view");
InsertGuiPair(menu_view_always_on_top, "&Always on top");
InsertGuiPair(menu_view_lang_english, "&English");
InsertGuiPair(menu_view_lang_polish, "&Polish");
InsertGuiPair(menu_view_close_program, "&Close");
InsertGuiPair(menu_view_edit_undo, "&Undo");
InsertGuiPair(menu_view_edit_paste, "&Paste");
InsertGuiPair(menu_view_edit_copy_result,"&Copy the result");
InsertGuiPair(menu_view_help_about, "&About");
InsertGuiPair(cant_init_calculations, "I could not initialize the module of calculations");
InsertGuiPair(message_box_error_caption,"TTCalc");
InsertGuiPair(cant_create_thread, "I could not create the second thread for calculating");
InsertGuiPair(cant_create_main_window, "I could not create the main window of the application");
InsertGuiPair(cant_init_common_controls,"I could not initialize the common controls (InitCommonControlsEx)");
InsertGuiPair(about_text,
"Mathematical calculator TTCalc %d.%d.%d\r\n"
"Author: Tomasz Sowa\r\n"
"Contact: t.sowa@slimaczek.pl\r\n"
"Licence: (New) BSD licence\r\n"
"Project page: \r\n"
"Mathemathical library: TTMath %d.%d.%d\r\n"
"Programming language: C++\r\n"
"Compiler: %s\r\n"
"\r\n"
"This program uses the TTMath mathematical library"
" which can be found at http://sourceforge.net/projects/ttmath\r\n"
"\r\n"
"If you have any questions, advices or interesting ideas about"
" this program or if you want to join to this project as"
" the developer or programmer just contact with me."
);
InsertGuiPair(about_box_title, "About");
// pl
gui_messages_tab.push_back( std::map<GuiMsg, std::string>() );
InsertGuiPair(button_ok,"Ok");
InsertGuiPair(button_cancel,"Anuluj");
InsertGuiPair(message_box_caption,"TTCalc");
InsertGuiPair(dialog_box_add_variable_caption,"Dodaj now¹ zmienn¹");
InsertGuiPair(dialog_box_edit_variable_caption,"Zmieñ wartoœæ zmiennej");
InsertGuiPair(dialog_box_add_variable_incorrect_name,"Nie prawid³owa nazwa zmiennej");
InsertGuiPair(dialog_box_add_variable_incorrect_value,"Nie prawid³owa wartoœæ zmiennej");
InsertGuiPair(dialog_box_add_variable_variable_exists,"Podana zmienna ju¿ istnieje");
InsertGuiPair(dialog_box_edit_variable_unknown_variable,"Podanej zmiennej nie ma w tablicy. Prawdopodobnie b³¹d wewnêtrzny programu.");
InsertGuiPair(dialog_box_delete_variable_confirm,"Czy napewno usun¹æ zaznaczone zmienne?");
InsertGuiPair(dialog_box_variable_not_all_deleted,"Zosta³o kilka zmiennych których nie mo¿na by³o skasowaæ. Prawdopodobnie b³¹d wewnêtrzny programu.");
InsertGuiPair(dialog_box_add_function_caption,"Dodaj now¹ funkcjê");
InsertGuiPair(dialog_box_edit_function_caption,"Zmieñ wartoœæ funkcji");
InsertGuiPair(dialog_box_add_function_function_exists,"Podana funkcja ju¿ istnieje");
InsertGuiPair(dialog_box_edit_function_unknown_function,"Podanej funkcji nie ma w tablicy. Prawdopodobnie b³¹d wewnêtrzny programu.");
InsertGuiPair(dialog_box_delete_function_confirm,"Czy napewno usun¹æ zaznaczone funkcje?");
InsertGuiPair(dialog_box_function_not_all_deleted,"Zosta³o kilka funkcji których nie mo¿na by³o skasowaæ. Prawdopodobnie b³¹d wewnêtrzny programu.");
InsertGuiPair(list_variables_header_1,"Nazwa");
InsertGuiPair(list_variables_header_2,"WartoϾ");
InsertGuiPair(list_functions_header_1,"Nazwa");
InsertGuiPair(list_functions_header_2,"Parametry");
InsertGuiPair(list_functions_header_3,"WartoϾ");
InsertGuiPair(button_add,"Dodaj");
InsertGuiPair(button_edit,"Edytuj");
InsertGuiPair(button_delete,"Usuñ");
InsertGuiPair(button_clear,"C");
InsertGuiPair(tab_standard,"Standard");
InsertGuiPair(tab_variables,"Zmienne");
InsertGuiPair(tab_functions,"Funkcje");
InsertGuiPair(tab_precision,"Precyzja");
InsertGuiPair(tab_display,"Wyœwietlanie");
InsertGuiPair(radio_precision_1,"Ma³a - 96 bitowa mantysa, 32 bitowy wyk³adnik");
InsertGuiPair(radio_precision_2,"Œrednia - 192 bitowa mantysa, 64 bitowy wyk³adnik");
InsertGuiPair(radio_precision_3,"Du¿a - 288 bitowa mantysa, 96 bitowy wyk³adnik");
InsertGuiPair(precision_1_info,"(+/-)6.9 e+646457021, 26 cyfr znacz¹cych (w rozwiniêciu dziesiêtnym)");
InsertGuiPair(precision_2_info,"(+/-)4.3 e+2776511644261678623, 56 cyfr znacz¹cych");
InsertGuiPair(precision_3_info,"(+/-)2.5 e+11925026709067095507636213441, 85 cyfr znacz¹cych");
InsertGuiPair(overflow_during_printing,"Przepe³nienie podczas wypisywania");
InsertGuiPair(combo_rounding_none,"bez zaokr¹glania");
InsertGuiPair(combo_rounding_cut_last_digits,"skasowaæ nie znacz¹ce zera");
InsertGuiPair(combo_rounding_integer,"do najbli¿szej ca³kowitej");
InsertGuiPair(combo_rounding_to_number,"do");
InsertGuiPair(combo_rounding_after_comma,"cyfr(y) po przecinku");
InsertGuiPair(display_input,"Wejœcie");
InsertGuiPair(display_output,"Wyjœcie");
InsertGuiPair(display_rounding,"Zaokr¹glenie");
InsertGuiPair(display_always_scientific,"Zawsze");
InsertGuiPair(display_not_always_scientific,"Jeœli eksponent wiêkszy ni¿");
InsertGuiPair(display_digit, "cyfr");
InsertGuiPair(display_group_scientific, "Wyœwietl wynik w postaci naukowej");
InsertGuiPair(menu_view, "&Widok");
InsertGuiPair(menu_edit, "&Edycja");
InsertGuiPair(menu_help, "&Pomoc");
InsertGuiPair(menu_language, "&Jêzyk");
InsertGuiPair(menu_view_new_window, "&Nowe okno");
InsertGuiPair(menu_view_normal_view, "Widok no&rmalny");
InsertGuiPair(menu_view_compact_view, "Widok &kompaktowy");
InsertGuiPair(menu_view_always_on_top, "Zawsze na &wierzchu");
InsertGuiPair(menu_view_lang_english, "Jêzyk &angielski");
InsertGuiPair(menu_view_lang_polish, "Jêzyk &polski");
InsertGuiPair(menu_view_close_program, "&Zamknij");
InsertGuiPair(menu_view_edit_undo, "&Cofnij");
InsertGuiPair(menu_view_edit_paste, "&Wklej");
InsertGuiPair(menu_view_edit_copy_result,"&Kopiuj wynik");
InsertGuiPair(menu_view_help_about, "&O programie");
InsertGuiPair(cant_init_calculations, "Nie uda³o siê zainicjalizowaæ modu³u obs³ugi obliczeñ");
InsertGuiPair(message_box_error_caption,"TTCalc");
InsertGuiPair(cant_create_thread, "Nie uda³o siê utworzyæ drugiego w¹tku do obliczeñ");
InsertGuiPair(cant_create_main_window, "Nie uda³o siê utworzyæ g³ównego okna aplikacji");
InsertGuiPair(cant_init_common_controls,"Nie uda³o siê zainicjalizowaæ obs³ugi Common Controls (InitCommonControlsEx)");
InsertGuiPair(about_text,
"Kalkulator matematyczny TTCalc %d.%d.%d\r\n"
"Autor: Tomasz Sowa\r\n"
"Kontakt: t.sowa@slimaczek.pl\r\n"
"Licencja: (New) BSD\r\n"
"Strona projektu: \r\n"
"Biblioteka matematyczna: TTMath %d.%d.%d\r\n"
"Jêzyk programowania: C++\r\n"
"Kompilator: %s\r\n"
"\r\n"
"Ten program u¿ywa biblioteki matematycznej TTMath"
" która jest dostêpna na http://sourceforge.net/projects/ttmath\r\n"
"\r\n"
"Je¿eli masz jakieœ pytania, rady, ciekawe pomys³y dotycz¹ce"
" tego programu lub chcia³byœ do³¹czyæ jako projektant/programista"
" poprostu skontaktuj siê ze mn¹."
);
InsertGuiPair(about_box_title, "O programie");
}

139
src/languages.h Normal file
View File

@ -0,0 +1,139 @@
#ifndef headerfilelanguages
#define headerfilelanguages
#include <string>
#include <map>
#include <vector>
#include <ttmath/ttmathtypes.h>
class Languages
{
public:
enum GuiMsg
{
button_ok,
button_cancel,
message_box_caption,
dialog_box_add_variable_caption,
dialog_box_edit_variable_caption,
dialog_box_add_variable_incorrect_name,
dialog_box_add_variable_incorrect_value,
dialog_box_add_variable_variable_exists,
dialog_box_edit_variable_unknown_variable,
dialog_box_delete_variable_confirm,
dialog_box_variable_not_all_deleted,
dialog_box_add_function_caption,
dialog_box_edit_function_caption,
dialog_box_add_function_function_exists,
dialog_box_edit_function_unknown_function,
dialog_box_delete_function_confirm,
dialog_box_function_not_all_deleted,
list_variables_header_1,
list_variables_header_2,
list_functions_header_1,
list_functions_header_2,
list_functions_header_3,
button_add,
button_edit,
button_delete,
button_clear,
tab_standard,
tab_variables,
tab_functions,
tab_precision,
tab_display,
radio_precision_1,
radio_precision_2,
radio_precision_3,
precision_1_info,
precision_2_info,
precision_3_info,
overflow_during_printing,
combo_rounding_none,
combo_rounding_cut_last_digits,
combo_rounding_integer,
combo_rounding_to_number,
combo_rounding_after_comma,
display_input,
display_output,
display_rounding,
display_always_scientific,
display_not_always_scientific,
menu_view,
menu_edit,
menu_help,
menu_language,
menu_view_new_window,
menu_view_normal_view,
menu_view_compact_view,
menu_view_always_on_top,
menu_view_lang_english,
menu_view_lang_polish,
menu_view_close_program,
menu_view_edit_undo,
menu_view_edit_paste,
menu_view_edit_copy_result,
menu_view_help_about,
cant_init_calculations,
message_box_error_caption,
cant_create_thread,
cant_create_main_window,
cant_init_common_controls,
about_text,
about_box_title,
display_digit,
display_group_scientific
};
// the first item must be with zero index
// and next items must be about one greater (0,1,2,3..)
// (after conversion to 'int' we pass it into the std::vector)
enum Country
{
en = 0, pl
};
private:
Country current_country;
std::vector<std::map<ttmath::ErrorCode, std::string> > error_messages_tab;
std::vector<std::map<GuiMsg, std::string> > gui_messages_tab;
void InsertErrorPair(ttmath::ErrorCode code, const char * message);
void InitErrorMessagesTab();
void InsertGuiPair(GuiMsg code, const char * message);
void InitGuiMessagesTab();
public:
Languages()
{
current_country = en;
}
void SetCurrentLanguage(Country c)
{
current_country = c;
}
Country GetCurrentLanguage()
{
return current_country;
}
const char * ErrorMessage(Country country, ttmath::ErrorCode code);
const char * ErrorMessage(ttmath::ErrorCode code);
const char * GuiMessage(Country country, GuiMsg code);
const char * GuiMessage(GuiMsg code);
};
#endif

754
src/mainwindow.cpp Normal file
View File

@ -0,0 +1,754 @@
#include "compileconfig.h"
#include "winmain.h"
namespace MainWindowFunctions
{
void SetActiveTab(unsigned int i)
{
static int last_shown_dialog = -1;
if( last_shown_dialog != -1 )