iup-stack/iup/srccontrols/matrixex/iupmatex_copy.c

268 lines
6.1 KiB
C
Raw Normal View History

2023-02-20 16:44:45 +00:00
/** \file
* \brief IupMatrix Expansion Library.
*
* See Copyright Notice in "iup.h"
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "iup.h"
#include "iupcbs.h"
#include "iup_array.h"
#include "iup_object.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_matrixex.h"
static void iMatrixExCopyColToSetDataSelected(ImatExData* matex_data, int lin, int col, int num_lin, const char* selection, int selection_count, const char* busyname)
{
int skip_lin = lin;
/* Must duplicate the memory to ensure it will be valid for all iterations */
char* value = iupStrDup(iupMatrixExGetCellValue(matex_data->ih, lin, col, 0)); /* get internal value */
iupMatrixExBusyStart(matex_data, selection_count, busyname);
for(lin = 1; lin <= num_lin; ++lin)
{
if (lin != skip_lin && selection[lin]=='1' && iupMatrixExIsLineVisible(matex_data->ih, lin))
{
iupMatrixExSetCellValue(matex_data->ih, lin, col, value);
if (!iupMatrixExBusyInc(matex_data))
{
free(value);
return;
}
}
}
iupMatrixExBusyEnd(matex_data);
free(value);
iupBaseCallValueChangedCb(matex_data->ih);
}
static void iMatrixExCopyColToSetData(ImatExData* matex_data, int lin, int col, int lin1, int lin2, const char* busyname)
{
int skip_lin = lin;
/* Must duplicate the memory to ensure it will be valid for all iterations */
char* value = iupStrDup(iupMatrixExGetCellValue(matex_data->ih, lin, col, 0)); /* get internal value */
iupMatrixExBusyStart(matex_data, lin2-lin1+1, busyname);
for(lin = lin1; lin <= lin2; ++lin)
{
if (lin != skip_lin && iupMatrixExIsLineVisible(matex_data->ih, lin))
{
iupMatrixExSetCellValue(matex_data->ih, lin, col, value);
if (!iupMatrixExBusyInc(matex_data))
{
free(value);
return;
}
}
}
iupMatrixExBusyEnd(matex_data);
free(value);
iupBaseCallValueChangedCb(matex_data->ih);
}
static int iMatrixExGetMarkedLines(Ihandle *ih, int num_lin, int num_col, int col, char* selection, int *selection_count)
{
char *marked = IupGetAttribute(ih, "MARKED");
if (!marked) /* no marked cells */
return 0;
selection[0] = '0';
*selection_count = 0;
if (*marked == 'C')
return 0;
else if (*marked == 'L')
{
int lin;
marked++;
for (lin=1; lin<=num_lin; lin++)
{
if (iupMatrixExIsLineVisible(ih, lin))
{
if (marked[lin-1] == '1')
{
selection[lin] = '1';
(*selection_count)++;
}
else
selection[lin] = '0';
}
else
selection[lin] = '0';
}
}
else
{
int lin;
for(lin = 1; lin <= num_lin; ++lin)
{
if (iupMatrixExIsLineVisible(ih, lin))
{
int pos = (lin-1) * num_col + (col-1); /* marked array does not include titles */
if (marked[pos] == '1')
{
selection[lin] = '1';
(*selection_count)++;
}
else
selection[lin] = '0';
}
else
selection[lin] = '0';
}
}
return 1;
}
static int iMatrixExStrGetInterval(const char* interval, int num_lin, char* selection, int *selection_count)
{
int lin1, lin2, len, value_len, ret;
char value[100];
memset(selection, '0', num_lin+1);
*selection_count = 0;
len = (int)strlen(interval);
do
{
const char* next_value = iupStrNextValue(interval, len, &value_len, ',');
if (value_len)
{
memcpy(value, interval, value_len);
value[value_len] = 0;
ret = iupStrToIntInt(value, &lin1, &lin2, '-');
if (ret == 1)
{
if (lin1<=0) lin1 = 1;
if (lin1>num_lin) lin1 = num_lin;
selection[lin1] = '1';
(*selection_count)++;
}
else if (ret == 2)
{
int lin;
iupMatrixExCheckLimitsOrder(&lin1, &lin2, 1, num_lin);
for(lin = lin1; lin <= lin2; ++lin)
{
selection[lin] = '1';
(*selection_count)++;
}
}
else
return 0;
}
interval = next_value;
len -= value_len+1;
} while (value_len);
return 1;
}
static int iMatrixExSetCopyColToAttribId2(Ihandle *ih, int lin, int col, const char* value)
{
ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA");
int lin1, lin2;
int num_lin, num_col;
char* busyname;
num_lin = IupGetInt(ih, "NUMLIN");
num_col = IupGetInt(ih, "NUMCOL");
if (col <= 0 ||
col > num_col ||
!iupMatrixExIsColumnVisible(ih, col))
return 0;
if (iupStrEqualNoCase(value, "ALL"))
{
busyname = "COPYCOLTO:ALL";
lin1 = 1;
lin2 = num_lin;
}
else if (iupStrEqualNoCase(value, "TOP"))
{
busyname = "COPYCOLTO:TOP";
lin1 = 1;
lin2 = lin-1;
}
else if (iupStrEqualNoCase(value, "BOTTOM"))
{
busyname = "COPYCOLTO:BOTTOM";
lin1 = lin+1;
lin2 = num_lin;
}
else if (iupStrEqualNoCase(value, "MARKED"))
{
int selection_count;
char* selection = (char*)malloc(num_lin+1);
iupAttribSet(ih, "LASTERROR", NULL);
if (!iMatrixExGetMarkedLines(ih, num_lin, num_col, col, selection, &selection_count))
{
iupAttribSet(ih, "LASTERROR", "IUP_ERRORNOSELECTION");
free(selection);
return 0;
}
iMatrixExCopyColToSetDataSelected(matex_data, lin, col, num_lin, selection, selection_count, "COPYCOLTO:MARKED");
free(selection);
return 0;
}
else
{
int selection_count;
char* selection = (char*)malloc(num_lin+1);
iupAttribSet(ih, "LASTERROR", NULL);
if (!iMatrixExStrGetInterval(value, num_lin, selection, &selection_count))
{
iupAttribSet(ih, "LASTERROR", "IUP_ERRORINVALIDINTERVAL");
free(selection);
return 0;
}
iMatrixExCopyColToSetDataSelected(matex_data, lin, col, num_lin, selection, selection_count, "COPYCOLTO:INTERVAL");
free(selection);
return 0;
}
iupMatrixExCheckLimitsOrder(&lin1, &lin2, 1, num_lin);
iMatrixExCopyColToSetData(matex_data, lin, col, lin1, lin2, busyname);
return 0;
}
void iupMatrixExRegisterCopy(Iclass* ic)
{
iupClassRegisterAttributeId2(ic, "COPYCOLTO", NULL, iMatrixExSetCopyColToAttribId2, IUPAF_NO_INHERIT);
}