1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "gtk_win.h"
char column_names[16][NUM_COLS];
void window_main(void) {
gtk_init(NULL, NULL);
GtkBuilder* builder = gtk_builder_new();
// Read glade XML config file
gtk_builder_add_from_file(builder, "/usr/share/tick/window_main.glade", NULL);
// Get widgets
GtkWidget* window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
GtkListStore* list = GTK_LIST_STORE(gtk_builder_get_object(builder, "check_list"));
GtkTreeView* tree_view = GTK_TREE_VIEW(gtk_builder_get_object(builder, "check_tree_view"));
for (gint i = 0; i < NUM_COLS; i++) // Copy names of columns into array
strcpy(column_names[i], gtk_tree_view_column_get_title(gtk_tree_view_get_column(
tree_view, i)));
Info_Array* portfolio_data = portfolio_get_info_array(); // Portfolio data
format_cells(portfolio_data); // Format portfolio data to strings
Info* idx; // Append list store with portfolio data
for (size_t i = 0; i < portfolio_data->length; i++) {
GtkTreeIter iter;
idx = portfolio_data->array[i];
gtk_list_store_append(list, &iter);
gtk_list_store_set(list, &iter, AMOUNT, idx->famount, SYMBOL, idx->symbol, VALUE,
idx->fcurrent_value, SPENT, idx->ftotal_spent, PROFIT,
idx->fprofit_total, PROFIT_PERCENT, idx->fprofit_total_percent,
PROFIT_24H, idx->fprofit_last_close, PROFIT_24H_PERCENT,
idx->fprofit_last_close_percent, PROFIT_7D, idx->fprofit_7d,
PROFIT_7D_PERCENT, idx->fprofit_7d_percent, PROFIT_30D, idx->fprofit_30d,
PROFIT_30D_PERCENT, idx->fprofit_30d_percent, -1);
}
GtkTreeIter iter;
gtk_list_store_append(list, &iter); // Add totals
gtk_list_store_set(list, &iter, SYMBOL, "TOTALS", VALUE, portfolio_data->fcurrent_value, SPENT,
portfolio_data->ftotal_spent, PROFIT, portfolio_data->fprofit_total,
PROFIT_PERCENT, portfolio_data->fprofit_total_percent, PROFIT_24H,
portfolio_data->fprofit_last_close, PROFIT_24H_PERCENT,
portfolio_data->fprofit_last_close_percent, PROFIT_7D,
portfolio_data->fprofit_7d, PROFIT_7D_PERCENT,
portfolio_data->fprofit_7d_percent, PROFIT_30D, portfolio_data->fprofit_30d,
PROFIT_30D_PERCENT, portfolio_data->fprofit_30d_percent, -1);
gtk_builder_connect_signals(builder, NULL); // Connect signals
g_object_unref(builder);
gtk_widget_show_all(window);
gtk_main(); // Main loop
api_info_array_destroy(&portfolio_data);
}
void format_cells(Info_Array* portfolio_data) {
Info* idx;
for (size_t i = 0; i < portfolio_data->length; i++) {
idx = portfolio_data->array[i];
sprintf(idx->famount, "%.2lf", idx->amount);
sprintf(idx->ftotal_spent, "%.2lf", idx->total_spent);
sprintf(idx->fcurrent_value, "%.2lf", idx->current_value);
sprintf(idx->fprofit_total, "%.2lf", idx->profit_total);
sprintf(idx->fprofit_total_percent, "%.2lf", idx->profit_total_percent);
sprintf(idx->fprofit_last_close, "%.2lf", idx->profit_last_close);
sprintf(idx->fprofit_last_close_percent, "%.2lf", idx->profit_last_close_percent);
sprintf(idx->fprofit_7d, "%.2lf", idx->profit_7d);
sprintf(idx->fprofit_7d_percent, "%.2lf", idx->profit_7d_percent);
sprintf(idx->fprofit_30d, "%.2lf", idx->profit_30d);
sprintf(idx->fprofit_30d_percent, "%.2lf", idx->profit_30d_percent);
}
sprintf(portfolio_data->ftotal_spent, "%.2lf", portfolio_data->total_spent);
sprintf(portfolio_data->fcurrent_value, "%.2lf", portfolio_data->current_value);
sprintf(portfolio_data->fprofit_total, "%.2lf", portfolio_data->profit_total);
sprintf(portfolio_data->fprofit_total_percent, "%.2lf", portfolio_data->profit_total_percent);
sprintf(portfolio_data->fprofit_last_close, "%.2lf", portfolio_data->profit_last_close);
sprintf(portfolio_data->fprofit_last_close_percent, "%.2lf",
portfolio_data->profit_last_close_percent);
sprintf(portfolio_data->fprofit_7d, "%.2lf", portfolio_data->profit_7d);
sprintf(portfolio_data->fprofit_7d_percent, "%.2lf", portfolio_data->profit_7d_percent);
sprintf(portfolio_data->fprofit_30d, "%.2lf", portfolio_data->profit_30d);
sprintf(portfolio_data->fprofit_30d_percent, "%.2lf",
portfolio_data->profit_30d_percent);
}
void on_main_win_destroy(void) {
gtk_main_quit();
}
void on_column_clicked(GtkTreeViewColumn* column, GtkListStore* list_store) {
int idx = -1;
for (int i = 0; i < NUM_COLS; i++)
if (strcmp(gtk_tree_view_column_get_title(column), column_names[i]) == 0)
idx = i;
list_store_sort(list_store, (Col_Index) idx);
}
void list_store_sort(GtkListStore* list_store, Col_Index idx) {
GtkTreeModel* model = (GtkTreeModel*) list_store;
int loop_flag = 1;
gchar* str1, * str2, * sym1, * sym2;
while (loop_flag) { // Bubble sort
loop_flag = 0;
GtkTreeIter iter1, iter2;
gtk_tree_model_get_iter_first(model, &iter1);
gtk_tree_model_get_iter_first(model, &iter2);
if (!gtk_tree_model_iter_next(model, &iter2)) // List length 1
return;
do {
gtk_tree_model_get(model, &iter1, SYMBOL, &sym1, -1);
gtk_tree_model_get(model, &iter2, SYMBOL, &sym2, -1);
// Don't sort TOTALS
if (strcmp(sym1, "TOTALS") != 0 && strcmp(sym2, "TOTALS") != 0) {
gtk_tree_model_get(model, &iter1, idx, &str1, -1);
gtk_tree_model_get(model, &iter2, idx, &str2, -1);
// Compare doubles
if ((idx != SYMBOL && strtod(str1, NULL) < strtod(str2, NULL)) ||
(idx == SYMBOL && strcmp(str1, str2) > 0)) { // Compare strings
gtk_list_store_swap(list_store, &iter1, &iter2);
loop_flag = 1;
}
g_free(str1);
g_free(str2);
}
g_free(sym1);
g_free(sym2);
} while (gtk_tree_model_iter_next(model, &iter1) &&
gtk_tree_model_iter_next(model, &iter2));
}
}
|