ttcalc/src/functions.cpp

315 lines
8.8 KiB
C++

/*
* This file is a part of TTCalc - a mathematical calculator
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* 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.
*/
#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