1 // This file is part of GtkEveMon.
2 //
3 // GtkEveMon is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // You should have received a copy of the GNU General Public License
9 // along with GtkEveMon. If not, see <http://www.gnu.org/licenses/>.
10
11 #include <string>
12 #include <sstream>
13
14 #include <glibmm.h>
15 #include <gtkmm.h>
16
17 #include "util/helpers.h"
18 #include "api/evetime.h"
19 #include "imagestore.h"
20 #include "gtkhelpers.h"
21
22 void
create_tooltip(Glib::RefPtr<Gtk::Tooltip> const & tooltip,ApiSkill const * skill,ApiCharSheetSkill * cskill,CharacterPtr character)23 GtkHelpers::create_tooltip (Glib::RefPtr<Gtk::Tooltip> const& tooltip,
24 ApiSkill const* skill, ApiCharSheetSkill* cskill,
25 CharacterPtr character)
26 {
27 tooltip->set_icon(ImageStore::skill);
28
29 std::stringstream ss;
30
31 if (cskill != 0)
32 ss << "Name: " << skill->name << " "
33 << Helpers::get_roman_from_int(cskill->level) << "\n";
34 else
35 ss << "Name: " << skill->name << "\n";
36
37 ss << "Attributes: " << ApiSkillTree::get_attrib_name(skill->primary)
38 << " / " << ApiSkillTree::get_attrib_name(skill->secondary)
39 << "\nRank: " << skill->rank << "\n";
40
41 if (cskill != 0 && cskill->level != 5)
42 {
43 /* Fill basic information available from the character skill. */
44 int current_sp = cskill->points;
45 double completed = cskill->completed;
46
47 /* Get more information available from char/training sheet. */
48 double spph = 0.0;
49 time_t time_remaining = 0;
50
51 if (character.get() != 0 && character->cs->valid)
52 {
53 /* Insert live information if the current skill is in training. */
54 if (character->is_training() && character->training_skill == skill)
55 {
56 /* Fill live information. */
57 current_sp = character->training_skill_sp;
58 completed = character->training_level_done;
59 spph = character->training_spph;
60 time_remaining = character->training_remaining;
61 }
62 else
63 {
64 /* Fill information from char sheet. */
65 int sp_remaining = cskill->points_dest - current_sp;
66 spph = (double)character->cs->get_spph_for_skill(skill);
67 time_remaining = (time_t)(3600.0 * (double)sp_remaining / spph);
68 }
69 }
70
71 ss << "Skill level from " << Helpers::get_dotted_str_from_int
72 (cskill->points_start) << " to " << Helpers::get_dotted_str_from_int
73 (cskill->points_dest) << " SP\n";
74
75 if (cskill->points_start != current_sp)
76 ss << "Current SP: " << Helpers::get_dotted_str_from_int
77 (current_sp) << "\n";
78
79 if (spph != 0.0 && time_remaining != 0)
80 {
81 ss << "SP per hour: " << (int)spph << "\n";
82 if (completed != 0.0)
83 ss << "Remaining time ";
84 else
85 ss << "Training time ";
86 ss << "to level " << Helpers::get_roman_from_int(cskill->level + 1) << ": ";
87 ss << EveTime::get_string_for_timediff(time_remaining, false) << "\n";
88 }
89
90 for (int level = cskill->level + 2; level <= 5; level++)
91 {
92 time_remaining = (time_t)(3600.0
93 * (double)(ApiCharSheet::calc_dest_sp(
94 level - 1, cskill->details->rank)
95 - ApiCharSheet::calc_start_sp(level - 1,
96 cskill->details->rank)) / spph);
97 ss << "Training time to level "
98 << Helpers::get_roman_from_int(level) << ": "
99 << EveTime::get_string_for_timediff(time_remaining, false) << "\n";
100 }
101
102 if (completed != 0.0)
103 ss << "Completed: " << Helpers::get_string_from_double
104 (completed * 100.0, 2) << "%\n";
105 }
106
107
108 #if 0
109 /* Old version without live SP counting. */
110 if (cskill != 0 && sheet.get() != 0 && sheet->valid && cskill->level != 5)
111 {
112 int sp_to_go = cskill->points_dest - cskill->points;
113 double spph = (double)sheet->get_spph_for_skill(skill);
114 time_t secs_next_level = (time_t)(3600.0 * (double)sp_to_go / spph);
115 std::string next_level_str = EveTime::get_string_for_timediff
116 (secs_next_level, false);
117 if (cskill->completed != 0.0)
118 next_level_str += " (" + Helpers::get_string_from_double
119 (cskill->completed * 100.0, 0) + "% completed)";
120 ss << "SP per hour: " << (int)(spph) << "\n"
121 << "Destination SP: "
122 << Helpers::get_dotted_str_from_int(cskill->points_dest) << "\n"
123 << "Training time: " << next_level_str << "\n";
124 }
125 #endif
126
127 ss << "\n" << skill->desc;
128 tooltip->set_text(ss.str());
129 }
130
131 /* ---------------------------------------------------------------- */
132
133 void
create_tooltip(Glib::RefPtr<Gtk::Tooltip> const & tooltip,ApiCert const * cert)134 GtkHelpers::create_tooltip (Glib::RefPtr<Gtk::Tooltip> const& tooltip,
135 ApiCert const* cert)
136 {
137 Glib::ustring class_name = cert->class_details->name;
138 Glib::ustring cert_grade = ApiCertTree::get_name_for_grade(cert->grade);
139 Glib::ustring cert_desc = cert->desc;
140
141 tooltip->set_icon(ImageStore::certificate);
142 tooltip->set_text("Name: " + class_name + "\nGrade: " + cert_grade
143 + "\n\n" + cert_desc);
144 }
145
146 /* ---------------------------------------------------------------- */
147
148 bool
create_tooltip_from_view(int x,int y,Glib::RefPtr<Gtk::Tooltip> tip,Gtk::TreeView & view,Glib::RefPtr<Gtk::TreeModel> store,Gtk::TreeModelColumn<ApiElement const * > col)149 GtkHelpers::create_tooltip_from_view (int x, int y,
150 Glib::RefPtr<Gtk::Tooltip> tip, Gtk::TreeView& view,
151 Glib::RefPtr<Gtk::TreeModel> store,
152 Gtk::TreeModelColumn<ApiElement const*> col)
153 {
154 Gtk::TreeModel::Path path;
155 Gtk::TreeViewDropPosition pos;
156 bool exists = view.get_dest_row_at_pos(x, y, path, pos);
157 if (!exists)
158 return false;
159
160 Gtk::TreeIter iter = store->get_iter(path);
161 ApiElement const* elem = (*iter)[col];
162 if (elem == 0)
163 return false;
164
165 /* Reposition tooltip. */
166 view.set_tooltip_row(tip, path);
167
168 switch (elem->get_type())
169 {
170 case API_ELEM_SKILL:
171 GtkHelpers::create_tooltip(tip, (ApiSkill const*)elem);
172 break;
173 case API_ELEM_CERT:
174 GtkHelpers::create_tooltip(tip, (ApiCert const*)elem);
175 break;
176 default:
177 return false;
178 }
179
180 return true;
181 }
182
183 /* ---------------------------------------------------------------- */
184
185 Glib::ustring
locale_to_utf8(Glib::ustring const & opsys_string)186 GtkHelpers::locale_to_utf8 (Glib::ustring const& opsys_string)
187 {
188 /* We don't throw the error further away, we'll handle it here. */
189 #define LOCALE_TO_UTF8_ERROR "Error converting string to UTF-8!"
190 #ifdef GLIBMM_EXCEPTIONS_ENABLED
191 try
192 { return Glib::locale_to_utf8(opsys_string); }
193 catch (...)
194 { return LOCALE_TO_UTF8_ERROR; }
195 #else
196 std::auto_ptr<Glib::Error> error;
197 std::string ret = Glib::locale_to_utf8(opsys_string, error);
198 if (error.get())
199 return LOCALE_TO_UTF8_ERROR;
200 return ret;
201 #endif
202 }
203