1 |
/* |
2 |
Copyright (c) 2014 - 2017 Christian Schoenebeck |
3 |
|
4 |
This file is part of "gigedit" and released under the terms of the |
5 |
GNU General Public License version 2. |
6 |
*/ |
7 |
|
8 |
#include "ReferencesView.h" |
9 |
#include "global.h" |
10 |
#include "compat.h" |
11 |
|
12 |
Glib::ustring gig_to_utf8(const gig::String& gig_string); |
13 |
Glib::ustring note_str(int note); |
14 |
|
15 |
ReferencesView::ReferencesView(Gtk::Window& parent) : |
16 |
ManagedDialog("", parent, true), m_sample(NULL), |
17 |
#if HAS_GTKMM_STOCK |
18 |
m_closeButton(Gtk::Stock::CLOSE), |
19 |
#else |
20 |
m_closeButton(_("_Close"), true), |
21 |
#endif |
22 |
m_descriptionLabel() |
23 |
{ |
24 |
set_title("Nothing selected"); |
25 |
|
26 |
#if !HAS_GTKMM_STOCK |
27 |
m_closeButton.set_icon_name("window-close"); |
28 |
#endif |
29 |
|
30 |
m_scrolledWindow.add(m_treeView); |
31 |
m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); |
32 |
|
33 |
#if USE_GTKMM_BOX |
34 |
get_content_area()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK); |
35 |
get_content_area()->pack_start(m_scrolledWindow); |
36 |
get_content_area()->pack_start(m_summaryLabel, Gtk::PACK_SHRINK); |
37 |
get_content_area()->pack_start(m_buttonBox, Gtk::PACK_SHRINK); |
38 |
#else |
39 |
get_vbox()->pack_start(m_descriptionLabel, Gtk::PACK_SHRINK); |
40 |
get_vbox()->pack_start(m_scrolledWindow); |
41 |
get_vbox()->pack_start(m_summaryLabel, Gtk::PACK_SHRINK); |
42 |
get_vbox()->pack_start(m_buttonBox, Gtk::PACK_SHRINK); |
43 |
#endif |
44 |
|
45 |
#if GTKMM_MAJOR_VERSION >= 3 |
46 |
m_descriptionLabel.set_line_wrap(); |
47 |
#endif |
48 |
m_descriptionLabel.set_text(_( |
49 |
"Selected sample is referenced by the following instruments and their " |
50 |
"respective regions. Click on a reference below to jump directly to " |
51 |
"its specific dimension region." |
52 |
)); |
53 |
|
54 |
m_refTreeModel = RefsTreeStore::create(m_columns); |
55 |
m_treeView.set_model(m_refTreeModel); |
56 |
m_treeView.set_tooltip_text(_( |
57 |
"Amount of times the selected sample in question is referenced. Click " |
58 |
"to jump to the specific reference." |
59 |
)); |
60 |
m_treeView.append_column(_("Name"), m_columns.m_col_name); |
61 |
m_treeView.append_column(_("References"), m_columns.m_col_refcount); |
62 |
m_treeView.set_headers_visible(true); |
63 |
m_treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); |
64 |
m_treeView.signal_row_activated().connect( |
65 |
sigc::mem_fun(*this, &ReferencesView::onSelectionChanged) |
66 |
); |
67 |
|
68 |
m_buttonBox.set_layout(Gtk::BUTTONBOX_END); |
69 |
#if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION > 22) |
70 |
m_buttonBox.set_margin(5); |
71 |
#else |
72 |
m_buttonBox.set_border_width(5); |
73 |
#endif |
74 |
m_buttonBox.pack_start(m_closeButton, Gtk::PACK_SHRINK); |
75 |
|
76 |
m_closeButton.signal_clicked().connect( |
77 |
sigc::mem_fun(*this, &ReferencesView::hide) |
78 |
); |
79 |
|
80 |
#if HAS_GTKMM_SHOW_ALL_CHILDREN |
81 |
show_all_children(); |
82 |
#endif |
83 |
} |
84 |
|
85 |
void ReferencesView::setSample(gig::Sample* sample) { |
86 |
m_refTreeModel->clear(); |
87 |
|
88 |
m_sample = sample; |
89 |
if (!sample) { |
90 |
set_title("Nothing selected"); |
91 |
m_summaryLabel.set_text(""); |
92 |
return; |
93 |
} |
94 |
|
95 |
set_title(_("References of Sample \"") + sample->pInfo->Name + "\""); |
96 |
|
97 |
int filesRefCount = 0; |
98 |
|
99 |
gig::File* gig = (gig::File*) sample->GetParent(); |
100 |
|
101 |
for (gig::Instrument* instrument = gig->GetFirstInstrument(); instrument; |
102 |
instrument = gig->GetNextInstrument()) |
103 |
{ |
104 |
Gtk::TreeModel::iterator iterInstr = m_refTreeModel->append(); |
105 |
Gtk::TreeModel::Row rowInstr = *iterInstr; |
106 |
rowInstr[m_columns.m_col_name] = gig_to_utf8(instrument->pInfo->Name); |
107 |
rowInstr[m_columns.m_col_instr] = instrument; |
108 |
rowInstr[m_columns.m_col_region] = NULL; |
109 |
|
110 |
int instrumentsRefcount = 0; |
111 |
for (gig::Region* rgn = instrument->GetFirstRegion(); rgn; |
112 |
rgn = instrument->GetNextRegion()) |
113 |
{ |
114 |
int regionsRefCount = 0; |
115 |
|
116 |
for (int i = 0; i < 256; ++i) { |
117 |
if (!rgn->pDimensionRegions[i]) continue; |
118 |
if (rgn->pDimensionRegions[i]->pSample != sample) continue; |
119 |
regionsRefCount++; |
120 |
} |
121 |
if (!regionsRefCount) continue; |
122 |
|
123 |
instrumentsRefcount += regionsRefCount; |
124 |
|
125 |
Gtk::TreeModel::iterator iterRegion = m_refTreeModel->append(rowInstr.children()); |
126 |
Gtk::TreeModel::Row rowRegion = *iterRegion; |
127 |
rowRegion[m_columns.m_col_name] = |
128 |
_("Region from ") + note_str(rgn->KeyRange.low) + _(" to ") + note_str(rgn->KeyRange.high); |
129 |
rowRegion[m_columns.m_col_instr] = NULL; |
130 |
rowRegion[m_columns.m_col_region] = rgn; |
131 |
rowRegion[m_columns.m_col_refcount] = |
132 |
ToString(regionsRefCount) + " " + _("Refs."); |
133 |
} |
134 |
|
135 |
if (!instrumentsRefcount) { |
136 |
m_refTreeModel->erase(iterInstr); |
137 |
continue; |
138 |
} |
139 |
|
140 |
rowInstr[m_columns.m_col_refcount] = |
141 |
ToString(instrumentsRefcount) + " " + _("Refs."); |
142 |
|
143 |
filesRefCount += instrumentsRefcount; |
144 |
} |
145 |
|
146 |
if (filesRefCount) |
147 |
m_summaryLabel.set_text(_("Total References: ") + ToString(filesRefCount)); |
148 |
else |
149 |
m_summaryLabel.set_text(_("This sample is not referenced at all.")); |
150 |
|
151 |
// unfold all instruments by default |
152 |
m_treeView.expand_all(); |
153 |
} |
154 |
|
155 |
void ReferencesView::onSelectionChanged(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { |
156 |
if (!m_sample) return; |
157 |
|
158 |
Gtk::TreeModel::iterator it = m_refTreeModel->get_iter(path); |
159 |
if (!it) return; |
160 |
|
161 |
Gtk::TreeModel::Row row = *it; |
162 |
|
163 |
gig::Instrument* pInstrument = row[m_columns.m_col_instr]; |
164 |
gig::Region* pRegion = row[m_columns.m_col_region]; |
165 |
gig::DimensionRegion* pDimRgn = NULL; |
166 |
if (pRegion) { |
167 |
// pick the 1st dimension region of that region referencing the sample |
168 |
for (int dr = 0; dr < pRegion->DimensionRegions && pRegion->pDimensionRegions[dr]; ++dr) { |
169 |
if (pRegion->pDimensionRegions[dr]->pSample == m_sample) { |
170 |
pDimRgn = pRegion->pDimensionRegions[dr]; |
171 |
break; |
172 |
} |
173 |
} |
174 |
} else if (pInstrument) { |
175 |
// pick the 1st region and its 1st dimension region referencing the sample |
176 |
for (pRegion = pInstrument->GetFirstRegion(); pRegion; pRegion = pInstrument->GetNextRegion()) { |
177 |
for (int dr = 0; dr < pRegion->DimensionRegions && pRegion->pDimensionRegions[dr]; ++dr) { |
178 |
if (pRegion->pDimensionRegions[dr]->pSample == m_sample) { |
179 |
pDimRgn = pRegion->pDimensionRegions[dr]; |
180 |
break; |
181 |
} |
182 |
} |
183 |
} |
184 |
} else { |
185 |
return; // no dimension region resolved to be selected, so do nothing |
186 |
} |
187 |
|
188 |
if (pDimRgn) { |
189 |
bool selectionSuccess = dimension_region_selected.emit(pDimRgn); |
190 |
if (selectionSuccess) hide(); |
191 |
} |
192 |
} |