File Coverage

blib/lib/Tk/TableEdit.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Tk::TableEdit;
2              
3 1     1   3768 use Tk;
  0            
  0            
4             use Tk::TabbedForm;
5             use Tk::SplitFrame;
6             use Tk::Columns;
7             use Tk::Frame;
8             use Tk::Pane;
9              
10             use base qw (Tk::Derived Tk::Frame);
11             use vars qw ($VERSION);
12             use strict;
13             use Carp;
14              
15             $VERSION = '0.01';
16              
17             Tk::Widget->Construct ('TableEdit');
18              
19             *separator = \&Tk::TableEdit::Separator;
20             *file = \&Tk::TableEdit::File;
21             *Save = \&Tk::TableEdit::Commit;
22             *Load = \&Tk::TableEdit::Fetch;
23              
24             sub Populate
25             {
26             my ($this, $p_Parameters) = (shift, @_);
27              
28             my $l_SplitFrame = $this->{m_SplitWidget} = $this->Component
29             (
30             'SplitFrame' => 'SplitFrame',
31             '-orientation' => 'vertical',
32             '-sliderposition' => 120,
33             '-padbefore' => 100,
34             '-padafter' => 200,
35             );
36              
37             my $l_ColumnWidget = $this->{m_ColumnWidget} = $l_SplitFrame->Component
38             (
39             'Columns' => 'Columns',
40             '-command' => sub {$this->SelectRow (@_);},
41             );
42              
43             my $l_Pane = $l_SplitFrame->Scrolled
44             (
45             'Pane',
46             '-scrollbars' => 'osoe',
47             '-relief' => 'flat',
48             '-borderwidth' => 2,
49             '-sticky' => 'nsew',
50             );
51              
52             my $l_TabWidget = $this->{m_TabWidget} = $l_Pane->Component
53             (
54             'TabbedForm' => 'TabFrame',
55             );
56              
57             my $l_ButtonFrame = $this->{m_ButtonFrame} = $this->Frame
58             (
59             '-borderwidth' => 0,
60             );
61              
62             $this->ConfigSpecs
63             (
64             '-tabfont' => [$l_TabWidget],
65             '-separator' => ['METHOD'],
66             '-file' => ['METHOD'],
67             );
68              
69             foreach my $l_Name (qw (Clear Insert Update Delete Reload Cancel OK Apply))
70             {
71             my $l_Button = $l_ButtonFrame->Button
72             (
73             '-command' => sub {$this->ButtonEvent ($l_Name, @_);},
74             '-text' => $l_Name,
75             '-borderwidth' => 1,
76             '-relief' => 'raised',
77             );
78              
79             $l_Button->pack
80             (
81             '-anchor' => 'nw',
82             '-side' => 'left',
83             );
84             }
85              
86             $l_TabWidget->pack
87             (
88             '-fill' => 'both',
89             '-expand' => 'true',
90             );
91              
92             $l_SplitFrame->place
93             (
94             '-anchor' => 'nw',
95             '-x' => 5,
96             '-y' => 5,
97             '-relwidth' => 1.0,
98             '-relheight' => 1.0,
99             '-height' => - (($l_ButtonFrame->children())[0]->reqheight() + 15),
100             '-width' => - 10,
101             );
102              
103             $l_ButtonFrame->place
104             (
105             '-x' => 5,
106             '-y' => - 5,
107             '-relwidth' => 1.0,
108             '-rely' => 1.0,
109             '-height' => ($l_ButtonFrame->children())[0]->reqheight(),
110             '-width' => - 10,
111             '-anchor' => 'sw',
112             );
113              
114             $this->GeometryRequest
115             (
116             $l_SplitFrame->reqwidth(),
117             $l_SplitFrame->reqheight() + $l_ButtonFrame->reqheight(),
118             );
119              
120             $this->bind
121             (
122             '' => sub {$this->Fetch() if ($this->{m_Changes} == 2);}
123             );
124              
125             $this->{m_SectionList} = [];
126             $this->configure ('-separator' => '|');
127             $this->SUPER::Populate (@_);
128             $this->{m_Changes} = 2;
129             return $this;
130             }
131              
132             sub Item
133             {
134             my $this = shift;
135              
136             my $l_Widget = $this->{m_TabWidget}->Item (@_);
137              
138             return unless (Exists ($l_Widget));
139              
140             if ($l_Widget->{m_SectionName} ne 'Global')
141             {
142             $this->{m_ColumnWidget}->configure
143             (
144             '-columnlabels' => [$this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList())],
145             );
146             }
147              
148             return $l_Widget;
149             }
150              
151             sub SetItemValues
152             {
153             my ($this, @p_Values) = @_;
154              
155             my @l_ItemArray = $this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList());
156              
157             for (my $l_Index = 0; $l_Index <= $#l_ItemArray; ++$l_Index)
158             {
159             $this->{m_TabWidget}->SetItemValue ($l_ItemArray [$l_Index], $p_Values [$l_Index]);
160             }
161             }
162              
163             sub GetItemValues
164             {
165             my ($this) = @_;
166             my @l_ItemArray = $this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList());
167             my @l_Array;
168              
169             for (my $l_Index = 0; $l_Index <= $#l_ItemArray; ++$l_Index)
170             {
171             push (@l_Array, $this->{m_TabWidget}->GetItemValue ($l_ItemArray [$l_Index]));
172             }
173              
174             return @l_Array;
175             }
176              
177             sub GetSectionNameList()
178             {
179             return (grep (!/^Global/, $_[0]->{m_TabWidget}->GetSectionNames()));
180             }
181              
182             sub SelectRow
183             {
184             my $this = shift;
185              
186             my $l_CurrentIndex = $this->CurrentIndex ($this->{m_ColumnWidget}->curselection());
187              
188             $this->SetItemValues
189             (
190             $l_CurrentIndex > -1 ?
191             $this->{m_ColumnWidget}->get ($l_CurrentIndex) :
192             ()
193             );
194             }
195              
196             sub CurrentIndex
197             {
198             my ($this, $p_Index) = (shift, @_);
199             return $this->{m_ColumnWidget}->curselection() unless (defined ($p_Index));
200             croak if ($p_Index < 0);
201             $this->{m_ColumnWidget}->selectionClear (0, 'end');
202             $this->{m_ColumnWidget}->selectionSet ($this->{m_Current} = $p_Index);
203             return $p_Index;
204             }
205              
206             sub Fetch
207             {
208             my ($this) = (shift, @_);
209             my $l_File = $this->cget (-file);
210             my $l_Buffer;
211              
212             return unless (defined ($l_File));
213              
214             $this->{m_ColumnWidget}->delete (0, 'end');
215              
216             if (defined (open (FILE, '<'.$l_File)))
217             {
218             while (defined ($l_Buffer = ))
219             {
220             chomp $l_Buffer;
221              
222             $this->RecordIn (split ('\\'.$this->{m_Separator}, $l_Buffer));
223             }
224              
225             $this->CurrentIndex (0);
226             $this->{m_Changes} = 0;
227             $this->SelectRow();
228             close (FILE);
229             }
230             }
231              
232             sub Commit
233             {
234             my ($this) = (shift, @_);
235             my $l_File = $this->cget ('-file');
236             my $l_Separator = $this->cget ('-separator');
237              
238             return unless ($this->{m_Changes} && defined ($l_File) && defined ($l_Separator));
239              
240             if (open (FILE, '>'.$l_File))
241             {
242             $this->Busy();
243              
244             printf FILE
245             (
246             "%s\n",
247             join ($l_Separator, ('Global', $this->{m_TabWidget}->GetItemNames ('Global')))
248             );
249              
250             printf FILE
251             (
252             "%s\n",
253             join ($this->{m_Separator}, $this->RecordOut ('Global'))
254             );
255              
256             printf FILE
257             (
258             "%s\n",
259             join ($l_Separator, ('Normal', $this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList())))
260             );
261              
262             for (my $l_Index = 0; $l_Index < $this->{m_ColumnWidget}->size(); ++$l_Index)
263             {
264             printf FILE
265             (
266             "%s\n",
267             join ($this->{m_Separator}, $this->RecordOut ($l_Index))
268             );
269             }
270              
271             $this->{m_Changes} = 0;
272             $this->Unbusy();
273             close (FILE);
274             }
275             }
276              
277             sub RecordOut
278             {
279             my $this = shift;
280             my $p_Index = shift;
281             my @l_Array = ('');
282              
283             if ($p_Index eq 'Global')
284             {
285             foreach my $l_Key ($this->{m_TabWidget}->GetItemNames ('Global'))
286             {
287             push (@l_Array, $this->{m_TabWidget}->GetItemValue ($l_Key));
288             }
289             }
290             elsif ($p_Index > -1)
291             {
292             push (@l_Array, $this->{m_ColumnWidget}->get ($p_Index));
293             }
294              
295             return @l_Array;
296             }
297              
298             sub RecordIn
299             {
300             my $this = shift;
301             my $l_Format = shift;
302              
303             if ($l_Format eq 'Global')
304             {
305             $this->{m_FormatType} = $l_Format;
306             @{$this->{m_Format}} = @_;
307             }
308             elsif ($l_Format eq 'Normal')
309             {
310             my @l_ItemArray = $this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList());
311             $this->{m_FormatType} = $l_Format;
312             @{$this->{m_Format}} = ();
313              
314             foreach my $l_Key (@_)
315             {
316             for (my $l_Index = 0; $l_Index <= $#l_ItemArray; ++$l_Index)
317             {
318             if ($l_Key eq $l_ItemArray [$l_Index])
319             {
320             push (@{$this->{m_Format}}, $l_Index);
321             }
322             }
323             }
324             }
325             elsif ($this->{m_FormatType} eq 'Global')
326             {
327             for (my $l_Index = 0; $l_Index <= $#{$this->{m_Format}}; ++$l_Index)
328             {
329             $this->{m_TabWidget}->SetItemValue (${$this->{m_Format}}[$l_Index], $_[$l_Index]);
330             }
331             }
332             elsif ($this->{m_FormatType} eq 'Normal')
333             {
334             my @l_Array;
335              
336             foreach my $l_Index (@{$this->{m_Format}})
337             {
338             $l_Array [$l_Index] = shift;
339             }
340              
341             $this->{m_ColumnWidget}->insert ('end', @l_Array);
342             }
343             }
344              
345             sub Separator
346             {
347             return ($_[0]->{m_Separator} = (defined ($_[1]) ? $_[1] : $_[0]->{m_Separator}));
348             }
349              
350             sub File
351             {
352             return ($_[0]->{m_File} = (defined ($_[1]) ? $_[1] : $_[0]->{m_File}));
353             }
354              
355             sub ButtonEvent
356             {
357             my ($this, $p_Command) = (shift, @_);
358              
359             my $l_ColumnWidget = $this->{m_ColumnWidget};
360              
361             if ($p_Command eq 'Clear')
362             {
363             foreach my $l_Key ($this->{m_TabWidget}->GetItemNames ($this->GetSectionNameList()))
364             {
365             $this->{m_TabWidget}->SetItemValue ($l_Key);
366             }
367             }
368             elsif ($p_Command eq 'Insert')
369             {
370             $l_ColumnWidget->insert ('end', $this->GetItemValues());
371             $this->CurrentIndex ($l_ColumnWidget->size() - 1);
372             $this->{m_Changes} = 1;
373             }
374             elsif ($p_Command eq 'Delete')
375             {
376             my $l_CurrentIndex = $this->CurrentIndex();
377             $l_ColumnWidget->delete ($l_CurrentIndex);
378             $this->CurrentIndex ($l_CurrentIndex - 1);
379             $this->{m_Changes} = 1;
380             $this->SelectRow();
381             }
382             elsif ($p_Command eq 'Reload')
383             {
384             $this->Fetch();
385             }
386              
387             if ($p_Command eq 'Apply' || $p_Command eq 'OK' || $p_Command eq 'Update')
388             {
389             my $l_CurrentIndex = $this->CurrentIndex();
390             $l_ColumnWidget->insert ($l_CurrentIndex, $this->GetItemValues());
391             $l_ColumnWidget->delete ($l_CurrentIndex + 1);
392             $this->CurrentIndex ($l_CurrentIndex);
393             $this->{m_Changes} = 1;
394             }
395              
396             if ($p_Command eq 'Apply' || $p_Command eq 'OK')
397             {
398             $this->Commit();
399             }
400              
401             if ($p_Command eq 'OK' || $p_Command eq 'Cancel')
402             {
403             $this->toplevel()->destroy();
404             }
405             }
406              
407             1;
408              
409             __END__