1#==========================================================
2# ImportExport --
3#
4#    provides for text transfers between files and PG
5#==========================================================
6#
7namespace eval ImportExport {
8    variable exim ; # 1 for import, 0 for export
9    variable eximtext
10    variable tablename
11    variable filename
12    variable delimiter
13    variable nullas
14    variable withoids
15}
16
17
18#----------------------------------------------------------
19# sets up the window for the import/export
20# defaults appropriate global vars if they arent passed as params
21# this is for use by the developers API
22#----------------------------------------------------------
23#
24proc ::ImportExport::setup {{exim_ 1} {tablename_ ""} {filename_ ""} {delimiter_ ""} {nullas_ ""} {withoids_ 0}} {
25
26    global PgAcVar CurrentDB
27
28    variable exim
29    variable eximtext
30    variable tablename
31    variable filename
32    variable delimiter
33    variable nullas
34    variable withoids
35
36    if {$CurrentDB==""} return;
37
38    set exim $exim_
39    set tablename $tablename_
40    set filename $filename_
41    set delimiter $delimiter_
42    set nullas $nullas_
43    set withoids $withoids_
44
45    # set default as tab output
46    if {$nullas==""} {
47        set nullas "\x00"
48    }
49    if {$delimiter==""} {
50        set delimiter "\x09"
51    }
52
53    if {$exim} {
54        set eximtext [intlmsg {Import}]
55    } else {
56        set eximtext [intlmsg {Export}]
57    }
58
59    # well if theres no filename we have to show a window and ask for one
60    if {$filename==""} {
61        # now we can export queries since they become temp tables first
62        if {$PgAcVar(activetab)==[intlmsg Queries] \
63          && ![winfo exists .pgaw:ImportExport]} {
64            Window show .pgaw:ImportExport
65            set tn [Mainlib::get_dwlb_Selection]
66            # okay this is odd but export needs to move around namespaces
67            if {[string length $tn]!=0} {
68                ::Queries::export [::Queries::getSQL $tn]
69            }
70        } else {
71            Window show .pgaw:ImportExport
72            if {$PgAcVar(activetab)==[intlmsg Tables]
73              || $PgAcVar(activetab)==[intlmsg Views] } {
74                set tn [Mainlib::get_dwlb_Selection]
75                set tablename $tn
76                if {$tn!=""} {set filename "$tn.txt"}
77            }
78            if {$exim} {
79                .pgaw:ImportExport.expbtn configure -text [intlmsg {Import}]
80            } else {
81                .pgaw:ImportExport.expbtn configure -text [intlmsg {Export}]
82            }
83        }
84    }
85
86}; # end proc ::ImportExport::setup
87
88
89#----------------------------------------------------------
90# performs the actual import or export
91#----------------------------------------------------------
92#
93proc ::ImportExport::execute {} {
94
95    global CurrentDB PgAcVar
96
97    variable exim
98    variable tablename
99    variable filename
100    variable delimiter
101    variable nullas
102    variable withoids
103
104    if {$tablename==""} {
105        showError [intlmsg "You have to supply a table name!"]
106    } elseif {$filename==""} {
107        showError [intlmsg "You have to supply a external file name!"]
108    } else {
109        # using delimiters ?
110        if {$delimiter==""} {
111            set delims ""
112        } elseif {$delimiter=="\x09"} {
113            set delims " USING DELIMITERS '\x09'"
114        } else {
115            set delims " USING DELIMITERS '$delimiter'"
116        }
117        # importing or exporting ?
118        if {$exim} {
119            set oper "FROM stdin"
120            set rw "r"
121        } else {
122            set oper "TO stdout"
123            set rw "w"
124        }
125        # using oids ?
126        if {$withoids} {
127            set withoids " WITH OIDS "
128        } else {
129            set withoids ""
130        }
131
132        set sqlcmd "COPY [::Database::quoteObject $tablename] $withoids $oper $delims WITH NULL AS '$nullas'"
133
134        if {[catch {::open "$filename" $rw} fid]} {
135            showError [intlmsg "Can't open the file $filename.  Check file permissions!"]
136        } else {
137            setCursor CLOCK
138
139            set pgres [wpg_exec $CurrentDB $sqlcmd]
140            set pgrestr [pg_result $pgres -status]
141
142            # importing
143            if {$pgrestr=="PGRES_COPY_IN"} {
144                set row 1
145                set bad_rows 0
146                set skip_row 0
147                while {![eof $fid]} {
148                    set bufcnt [gets $fid buf]
149                    if {$bufcnt>0} {
150                        catch {puts $CurrentDB $buf}
151                    }
152                    set pgrestr [pg_result $pgres -status]
153                }
154                # file is done
155                if {$pgrestr=="PGRES_COPY_IN"} {
156                    if {[catch {puts $CurrentDB "\\."}]} {
157                        # the transfer failed to complete
158                        set pgrestr [pg_result $pgres -status]
159                        showError [intlmsg "Failed to import!\n$pgrestr"]
160                    }
161                    # This finishes the copy for pgin.tcl:
162                    if {[info exists PgAcVar(PGINTCL)]} {
163                        pg_endcopy $pgres
164                    }
165                }
166            # exporting
167            } elseif {$pgrestr=="PGRES_COPY_OUT"} {
168                while {$pgrestr=="PGRES_COPY_OUT"} {
169                    set bufcnt [gets $CurrentDB buf]
170                    # This test is for pgin.tcl:
171                    if {$bufcnt == 2 && $buf == "\\."} {
172                        break
173                    }
174                    if {$bufcnt>0} {
175                        catch {puts $fid $buf}
176                    }
177                    set pgrestr [pg_result $pgres -status]
178                }
179                # This finishes the copy for pgin.tcl:
180                if {[info exists PgAcVar(PGINTCL)]} {
181                    pg_endcopy $pgres
182                }
183            # not sure how we get here but
184            } else {
185                showError [intlmsg "Another import/export is occurring.  Please wait!\n$pgrestr"]
186            }
187            set pgrestr [pg_result $pgres -status]
188            setCursor DEFAULT
189            pg_result $pgres -clear
190            ::close $fid
191            if {$pgrestr=="PGRES_COMMAND_OK"} {
192                # only say we are finished if fired from the menu command
193                if {[winfo exists .pgaw:ImportExport]} {
194                    tk_messageBox -title [intlmsg Information] \
195                        -message [intlmsg "Operation completed!"]
196                }
197            } else {
198                showError [intlmsg "Failed to import/export!\n$pgrestr"]
199            }
200        }
201    }
202
203}; # end proc ::ImportExport::execute
204
205
206
207### END ImportExport NAMESPACE ###
208### BEGIN ImportExport::wizard NAMESPACE ###
209
210
211
212namespace eval ImportExport::wizard {
213    variable curr_step
214    variable first_step 1
215    variable last_step 4
216    variable start_file_line 0
217    variable stop_file_line 0
218    variable colhdr
219    variable decoration
220    variable row_head
221    variable row_foot
222    variable page_head
223    variable page_foot
224    variable presets "TAB"
225    variable filecolhdrs
226    variable tablecols
227    variable progbar 0
228    variable transblock
229    variable truncate
230    variable overwrite
231    variable Win
232    variable Cols
233}
234
235
236#----------------------------------------------------------
237# this proc is used to create the tkwizard widget
238#----------------------------------------------------------
239#
240proc ::ImportExport::wizard::start_tkwizard {} {
241
242    variable ::ImportExport::exim
243    variable ::ImportExport::eximtext
244
245    variable Win
246
247    set Win(wiz) .pgaw:ImportExportWizard
248
249    if {[winfo exists $Win(wiz)]} {
250        destroy $Win(wiz)
251    }
252
253    set wiztit ""
254    if {$exim} {
255        set eximtext [intlmsg {Import}]
256        set wiztit [intlmsg {Import Wizard}]
257    } else {
258        set eximtext [intlmsg {Export}]
259        set wiztit [intlmsg {Export Wizard}]
260    }
261
262
263    tkwizard::tkwizard $Win(wiz) \
264        -title $wiztit \
265        -geometry 500x400+100+80
266
267    $Win(wiz) eval {
268        variable wizData
269        # default values
270        catch {unset wizData}
271    }
272
273    $Win(wiz) step {step_welcome} -layout advanced {
274        variable wizData
275        set c [$this widget clientArea]
276        if {$::ImportExport::exim} {
277            $this stepconfigure \
278                -title [intlmsg {Welcome to the Import Wizard!}] \
279                -subtitle [intlmsg {You must select a file name.  If the table you choose does not exist, it will be created for you.}] \
280                -pretext {} \
281                -posttext {}
282        } else {
283            $this stepconfigure \
284                -title [intlmsg {Welcome to the Export Wizard!}] \
285                -subtitle [intlmsg {You must select a table name.  If the file you choose does not exist, it will be created for you.}] \
286                -pretext {} \
287                -posttext {}
288        }
289        ::ImportExport::wizard::add_step_welcome $c
290    }; # end step_welcome
291
292    $Win(wiz) step {step_file} -layout basic {
293        variable wizData
294        set c [$this widget clientArea]
295        $this stepconfigure \
296            -title [intlmsg {Choose file characteristics}] \
297            -subtitle {} \
298            -pretext {} \
299            -posttext {}
300        ::ImportExport::wizard::set_presets
301        ::ImportExport::wizard::add_step_file $c
302        ::ImportExport::wizard::step_file_redraw
303    }; # end step_file
304
305    $Win(wiz) step {step_table} -layout basic {
306        variable wizData
307        set c [$this widget clientArea]
308        $this stepconfigure \
309            -title [intlmsg {Choose table characteristics}] \
310            -subtitle {} \
311            -pretext {} \
312            -posttext {}
313        ::ImportExport::wizard::add_step_table $c
314    }; # end step_table
315
316    $Win(wiz) step {step_finish} -layout advanced {
317        variable wizData
318        set c [$this widget clientArea]
319        if {$::ImportExport::exim} {
320            $this stepconfigure \
321                -title [intlmsg {Perform Import}] \
322                -subtitle [intlmsg {Finally, you can watch the progress of your operation.  Error messages will be written below.}] \
323                -pretext {} \
324                -posttext {}
325        } else {
326            $this stepconfigure \
327                -title [intlmsg {Perform Export}] \
328                -subtitle [intlmsg {Finally, you can watch the progress of your operation.  Error messages will be written below.}] \
329                -pretext {} \
330                -posttext {}
331        }
332        ::ImportExport::wizard::add_step_finish $c
333    }; # end step_finish
334
335    bind $Win(wiz) <<WizNextStep>> {::ImportExport::wizard::check_step %W}
336
337    $Win(wiz) show
338
339}; # end proc ::ImportExport::wizard::start_tkwizard
340
341
342#----------------------------------------------------------
343#----------------------------------------------------------
344#
345proc ::ImportExport::wizard::check_step {wiz_} {
346
347    variable ::tkwizard::wizData
348
349    variable ::ImportExport::exim
350    variable ::ImportExport::filename
351    variable ::ImportExport::tablename
352
353    variable Win
354
355    set currstep [$wiz_ cget -step]
356
357    switch $currstep {
358
359        "step_welcome" {
360            if {$exim} {
361                if {[string length [string trim $filename]]==0} {
362                    showError [intlmsg "You must supply a filename."]
363                    return -code break
364                } elseif {[string length [string trim $tablename]]==0} {
365                    showError [intlmsg "You must supply a tablename."]
366                    return -code break
367                } elseif {![file readable $filename]} {
368                    showError [intlmsg "Can't open the file.  Check file permissions!"]
369                    return -code break
370                } else {
371                    return
372                }
373            }
374        }
375
376     }; # end switch
377
378}; # end proc ::ImportExport::wizard::check_step
379
380
381#----------------------------------------------------------
382#----------------------------------------------------------
383#
384proc ::ImportExport::wizard::add_step_welcome {base_} {
385
386    variable ::ImportExport::exim
387
388    variable Win
389
390    set base $base_.fwel
391    set Win(step_welcome) $base_
392
393    frame $base
394    pack $base \
395        -in $base_ \
396        -fill both \
397        -expand 1
398
399    set row 0
400
401    Label $base.ltbl \
402        -anchor e \
403        -text [intlmsg {Table}]
404    ComboBox $base.cbtbl \
405        -editable true \
406        -textvariable ::ImportExport::tablename \
407        -values [::Database::getTablesList]
408    # if export, we must have a table name
409    if {!$::ImportExport::exim} {
410        $base.cbtbl configure -editable false
411    }
412    grid $base.ltbl \
413        -in $base \
414        -sticky news \
415        -row $row \
416        -column 0 \
417        -columnspan 1 \
418        -rowspan 1
419    grid $base.cbtbl \
420        -in $base \
421        -sticky news \
422        -row $row \
423        -column 1 \
424        -columnspan 4 \
425        -rowspan 1
426    incr row
427
428    Label $base.lfile \
429        -anchor e \
430        -text [intlmsg {File}]
431    Entry $base.efile \
432        -textvariable ::ImportExport::filename
433    Button $base.bfile \
434        -text [intlmsg {Browse}] \
435        -command {
436            set types {
437                {{Text Files}    {.txt}}
438                {{CSV Files}     {.csv}}
439                {{TAB Files}     {.tab}}
440                {{HTML Files}     {.html}}
441                {{All Files}          *}
442            }
443            if {$::ImportExport::exim} {
444                set tkget "tk_getOpenFile"
445                if {[catch {$tkget \
446                    -parent $::ImportExport::wizard::Win(wiz) \
447                    -filetypes $types \
448                    -title [intlmsg {Import}]} \
449                    ::ImportExport::filename] || \
450                    [string match {} $::ImportExport::filename]} return
451            } else {
452                set tkget "tk_getSaveFile"
453                if {[catch {$tkget \
454                    -parent $::ImportExport::wizard::Win(wiz) \
455                    -filetypes $types \
456                    -title [intlmsg {Export}]} \
457                    ::ImportExport::filename] || \
458                    [string match {} $::ImportExport::filename]} return
459            }
460            set ::ImportExport::wizard::start_file_line 0
461            set ::ImportExport::wizard::stop_file_line 0
462        }
463    grid $base.lfile \
464        -in $base \
465        -sticky news \
466        -row $row \
467        -column 0 \
468        -columnspan 1 \
469        -rowspan 1
470    grid $base.efile \
471        -in $base \
472        -sticky news \
473        -row $row \
474        -column 1 \
475        -columnspan 3 \
476        -rowspan 1
477    grid $base.bfile \
478        -in $base \
479        -row $row \
480        -column 4 \
481        -columnspan 1 \
482        -rowspan 1
483    incr row
484
485    Label $base.lpre \
486        -anchor e \
487        -text [intlmsg {Presets}]
488    ComboBox $base.cbpre \
489        -editable true \
490        -textvariable ::ImportExport::wizard::presets \
491        -values [list TAB CSV HTML WHITESPACE]
492    grid $base.lpre \
493        -in $base \
494        -sticky news \
495        -row $row \
496        -column 0 \
497        -columnspan 1 \
498        -rowspan 1
499    grid $base.cbpre \
500        -in $base \
501        -sticky news \
502        -row $row \
503        -column 1 \
504        -columnspan 4 \
505        -rowspan 1
506    incr row
507
508}; # end proc ::ImportExport::wizard::add_step_welcome
509
510
511#----------------------------------------------------------
512#----------------------------------------------------------
513#
514proc ::ImportExport::wizard::add_step_file {base_} {
515
516    global PgAcVar
517
518    variable Win
519
520    variable ::ImportExport::exim
521
522    #
523    # common file characteristics for both import and export
524    #
525
526    set Win(step_file) $base_
527
528    set base $base_.fgrid
529    set Win(step_file_grid) $base
530
531    set row 0
532
533    frame $base
534
535    pack $base \
536        -in $base_ \
537        -expand 1 \
538        -fill both
539
540    Label $base.ldelim \
541        -anchor e \
542        -text [intlmsg {Delimeter}]
543    ComboBox $base.cbdelim \
544        -editable true \
545        -textvariable ::ImportExport::delimiter \
546        -values [list "\x09" , \" \' \: " " "</td><td>"] \
547        -command {::ImportExport::wizard::step_file_redraw} \
548        -modifycmd {::ImportExport::wizard::step_file_redraw}
549    grid $base.ldelim \
550        -in $base \
551        -sticky news \
552        -row $row \
553        -column 0 \
554        -columnspan 1 \
555        -rowspan 1
556    grid $base.cbdelim \
557        -in $base \
558        -sticky news \
559        -row $row \
560        -column 1 \
561        -columnspan 1 \
562        -rowspan 1
563    incr row
564
565    Label $base.ldecor \
566        -anchor e \
567        -text [intlmsg {Decoration}]
568    ComboBox $base.cbdecor \
569        -editable true \
570        -textvariable ::ImportExport::wizard::decoration \
571        -values [list \" \'] \
572        -command {::ImportExport::wizard::step_file_redraw} \
573        -modifycmd {::ImportExport::wizard::step_file_redraw}
574    grid $base.ldecor \
575        -in $base \
576        -sticky news \
577        -row $row \
578        -column 0 \
579        -columnspan 1 \
580        -rowspan 1
581    grid $base.cbdecor \
582        -in $base \
583        -sticky news \
584        -row $row \
585        -column 1 \
586        -columnspan 1 \
587        -rowspan 1
588    incr row
589
590    Label $base.lnull \
591        -anchor e \
592        -text [intlmsg {Null As}]
593    ComboBox $base.cbnull \
594        -editable true \
595        -textvariable ::ImportExport::nullas \
596        -values [list "\x00" "(empty)" "NULL"] \
597        -command {::ImportExport::wizard::step_file_redraw} \
598        -modifycmd {::ImportExport::wizard::step_file_redraw}
599    grid $base.lnull \
600        -in $base \
601        -sticky news \
602        -row $row \
603        -column 0 \
604        -columnspan 1 \
605        -rowspan 1
606    grid $base.cbnull \
607        -in $base \
608        -sticky news \
609        -row $row \
610        -column 1 \
611        -columnspan 1 \
612        -rowspan 1
613    incr row
614
615    Label $base.lcolhdr \
616        -anchor e \
617        -text [intlmsg {Column Headers}]
618    checkbutton $base.cbcolhdr \
619        -variable ::ImportExport::wizard::colhdr \
620        -text [intlmsg {Use first row of file ?}] \
621        -command {::ImportExport::wizard::step_file_redraw}
622    grid $base.lcolhdr \
623        -in $base \
624        -sticky news \
625        -row $row \
626        -column 0 \
627        -columnspan 1 \
628        -rowspan 1
629    grid $base.cbcolhdr \
630        -in $base \
631        -sticky news \
632        -row $row \
633        -column 1 \
634        -columnspan 1 \
635        -rowspan 1
636    incr row
637
638    Label $base.lrowhead \
639        -anchor e \
640        -text [intlmsg {Row Header}]
641    ComboBox $base.cbrowhead \
642        -editable true \
643        -textvariable ::ImportExport::wizard::row_head \
644        -values [list "<tr><td>"] \
645        -command {::ImportExport::wizard::step_file_redraw} \
646        -modifycmd {::ImportExport::wizard::step_file_redraw}
647    grid $base.lrowhead \
648        -in $base \
649        -sticky news \
650        -row $row \
651        -column 0 \
652        -columnspan 1 \
653        -rowspan 1
654    grid $base.cbrowhead \
655        -in $base \
656        -sticky news \
657        -row $row \
658        -column 1 \
659        -columnspan 1 \
660        -rowspan 1
661    incr row
662
663    Label $base.lrowfoot \
664        -anchor e \
665        -text [intlmsg {Row Footer}]
666    ComboBox $base.cbrowfoot \
667        -editable true \
668        -textvariable ::ImportExport::wizard::row_foot \
669        -values [list "</td></tr>"] \
670        -command {::ImportExport::wizard::step_file_redraw} \
671        -modifycmd {::ImportExport::wizard::step_file_redraw}
672    grid $base.lrowfoot \
673        -in $base \
674        -sticky news \
675        -row $row \
676        -column 0 \
677        -columnspan 1 \
678        -rowspan 1
679    grid $base.cbrowfoot \
680        -in $base \
681        -sticky news \
682        -row $row \
683        -column 1 \
684        -columnspan 1 \
685        -rowspan 1
686    incr row
687
688    # now the import specific stuff
689    if {$exim} {
690
691        Label $base.lstart \
692            -anchor e \
693            -text [intlmsg {Start Line}]
694        SpinBox $base.sbstart \
695            -textvariable ::ImportExport::wizard::start_file_line \
696            -modifycmd {::ImportExport::wizard::step_file_redraw}
697        grid $base.lstart \
698            -in $base \
699            -sticky news \
700            -row $row \
701            -column 0 \
702            -columnspan 1 \
703            -rowspan 1
704        grid $base.sbstart \
705            -in $base \
706            -sticky news \
707            -row $row \
708            -column 1 \
709            -columnspan 1 \
710            -rowspan 1
711        incr row
712
713        Label $base.lstop \
714            -anchor e \
715            -text [intlmsg {Stop Line}]
716        SpinBox $base.sbstop \
717            -textvariable ::ImportExport::wizard::stop_file_line
718        grid $base.lstop \
719            -in $base \
720            -sticky news \
721            -row $row \
722            -column 0 \
723            -columnspan 1 \
724            -rowspan 1
725        grid $base.sbstop \
726            -in $base \
727            -sticky news \
728            -row $row \
729            -column 1 \
730            -columnspan 1 \
731            -rowspan 1
732        incr row
733
734        #
735        # tablelist for file preview
736        #
737
738        set base $base_.ftable
739        set Win(step_file_tablelist) $base
740
741        frame $base \
742            -borderwidth 5
743
744        scrollbar $base.xscroll \
745            -width 12 \
746            -command [list $base.tlfile xview] \
747            -highlightthickness 0 \
748            -orient horizontal \
749            -background #DDDDDD \
750            -takefocus 0
751        scrollbar $base.yscroll \
752            -width 12 \
753            -command [list $base.tlfile yview] \
754            -highlightthickness 0 \
755            -background #DDDDDD \
756            -takefocus 0
757
758        ::tablelist::tablelist $base.tlfile \
759            -yscrollcommand [list $base.yscroll set] \
760            -xscrollcommand [list $base.xscroll set] \
761            -background #fefefe \
762            -stripebg #e0e8f0 \
763            -selectbackground #DDDDDD \
764            -selectmode extended \
765            -labelfont $PgAcVar(pref,font_bold) \
766            -stretch all \
767            -columns [list 0 [intlmsg {First 10 lines of file}] left] \
768            -selectforeground #708090 \
769            -labelbackground #DDDDDD \
770            -labelforeground navy \
771            -height 5 \
772            -width 50
773
774        pack $base_.ftable.xscroll \
775            -in $base_.ftable \
776            -side bottom \
777            -fill x
778        pack $base_.ftable.yscroll \
779            -in $base_.ftable \
780            -side right \
781            -fill y
782        pack $base_.ftable.tlfile \
783            -in $base_.ftable \
784            -side right \
785            -anchor nw \
786            -expand 1 \
787            -fill both
788        pack $base_.ftable \
789            -in $base_ \
790            -fill both \
791            -expand 1
792
793    } else {
794
795        # export specific stuff, mostly for HTML output
796        # used to include row header/footer
797        # but thats useful for HTML imports
798        # so just worry about the page header/footer for
799        # export
800
801        Label $base.lpagehead \
802            -anchor e \
803            -text [intlmsg {Page Header}]
804        ComboBox $base.cbpagehead \
805            -editable true \
806            -textvariable ::ImportExport::wizard::page_head \
807            -values [list "<table>"] \
808            -command {::ImportExport::wizard::step_file_redraw} \
809            -modifycmd {::ImportExport::wizard::step_file_redraw}
810        grid $base.lpagehead \
811            -in $base \
812            -sticky news \
813            -row $row \
814            -column 0 \
815            -columnspan 1 \
816            -rowspan 1
817        grid $base.cbpagehead \
818            -in $base \
819            -sticky news \
820            -row $row \
821            -column 1 \
822            -columnspan 1 \
823            -rowspan 1
824        incr row
825
826        Label $base.lpagefoot \
827            -anchor e \
828            -text [intlmsg {Page Footer}]
829        ComboBox $base.cbpagefoot \
830            -editable true \
831            -textvariable ::ImportExport::wizard::page_foot \
832            -values [list "</table>"] \
833            -command {::ImportExport::wizard::step_file_redraw} \
834            -modifycmd {::ImportExport::wizard::step_file_redraw}
835        grid $base.lpagefoot \
836            -in $base \
837            -sticky news \
838            -row $row \
839            -column 0 \
840            -columnspan 1 \
841            -rowspan 1
842        grid $base.cbpagefoot \
843            -in $base \
844            -sticky news \
845            -row $row \
846            -column 1 \
847            -columnspan 1 \
848            -rowspan 1
849        incr row
850
851    }
852
853}; # end proc ::ImportExport::wizard::add_step_file
854
855
856#----------------------------------------------------------
857#----------------------------------------------------------
858#
859proc ::ImportExport::wizard::add_step_table {base_} {
860
861    global PgAcVar
862
863    variable ::ImportExport::exim
864    variable ::ImportExport::tablename
865    variable ::ImportExport::filename
866
867    variable colhdr
868    variable filecolhdrs
869    variable Cols
870
871    variable createtable
872    variable tablecols
873    variable fileline [list]
874    variable start_file_line
875
876    set base $base_.fgrid
877
878    set Win(step_table) $base_
879    set Win(step_table_grid) $base
880
881    set tablename [::Database::quoteObject $tablename]
882
883    # do we have to create the table
884    if { ![::Database::isTable $tablename] } {
885        if {$exim} {
886            set createtable 1
887        } else {
888            # for TEMP tables, tablecols was already set
889            set createtable 0
890        }
891    } else {
892        set createtable 0
893        set tablecols [::Database::getColumnsList $tablename]
894    }
895
896    # get us the line we are starting on from the file to show in a column
897    if {$exim} {
898        set fid [::open "$filename" r]
899        for {set i 0} {$i<$start_file_line && ![eof $fid]} {incr i} {
900            set bufcnt [gets $fid buf]
901        }
902        ::close $fid
903        set fileline [parse_lof $buf]
904    }
905
906    frame $base
907
908    set row 0
909    set col 0
910
911    Label $base.lfilecol \
912        -font $PgAcVar(pref,font_bold) \
913        -text [intlmsg {File}]
914    grid $base.lfilecol \
915        -in $base \
916        -sticky news \
917        -row $row \
918        -column $col \
919        -columnspan 1 \
920        -rowspan 1
921    incr col
922
923    if {$exim} {
924        Label $base.ltablecol \
925            -font $PgAcVar(pref,font_bold) \
926            -text [intlmsg {Table}]
927        grid $base.ltablecol \
928            -in $base \
929            -sticky news \
930            -row $row \
931            -column $col \
932            -columnspan 1 \
933            -rowspan 1
934        incr col
935        if {$createtable} {
936            Label $base.ltype \
937                -font $PgAcVar(pref,font_bold) \
938                -text [intlmsg {Type}]
939            grid $base.ltype \
940                -in $base \
941                -sticky news \
942                -row $row \
943                -column $col \
944                -columnspan 1 \
945                -rowspan 1
946            incr col
947        }
948        Label $base.lfileline \
949            -font $PgAcVar(pref,font_bold) \
950            -text [intlmsg {Start Line}]
951        grid $base.lfileline \
952            -in $base \
953            -sticky news \
954            -row $row \
955            -column $col \
956            -columnspan 1 \
957            -rowspan 1
958        incr col
959    }
960    Label $base.lskip \
961        -font $PgAcVar(pref,font_bold) \
962        -text [intlmsg {Skip}]
963    grid $base.lskip \
964        -in $base \
965        -sticky news \
966        -row $row \
967        -column $col \
968        -columnspan 1 \
969        -rowspan 1
970
971    incr row
972
973    # loop thru file column headers and start line in file for import
974    # loop thru column names for export
975    set looper [list]
976    if {$exim} {
977        set looper $filecolhdrs
978    } else {
979        set looper $tablecols
980    }
981
982    foreach fch $looper fln $fileline {
983        set slop "$row$col[join $fch _]"
984        set col 0
985        Label $base.l$slop \
986            -anchor e \
987            -text "$fch"
988        grid $base.l$slop \
989            -in $base \
990            -sticky news \
991            -row $row \
992            -column $col \
993            -columnspan 1 \
994            -rowspan 1
995        incr col
996        if {$exim} {
997            ComboBox $base.cb$slop \
998                -editable true \
999                -text "$fch" \
1000                -textvariable ::ImportExport::wizard::Cols($fch,name)
1001            grid $base.cb$slop \
1002                -in $base \
1003                -sticky news \
1004                -row $row \
1005                -column $col \
1006                -columnspan 1 \
1007                -rowspan 1
1008            incr col
1009            if {!$createtable} {
1010                $base.cb$slop configure -values $tablecols
1011                $base.cb$slop configure -editable false
1012            } else {
1013                ComboBox $base.cbtype$slop \
1014                    -editable true \
1015                    -text "text" \
1016                    -values [::Database::getAllColumnTypes] \
1017                    -textvariable ::ImportExport::wizard::Cols($fch,type)
1018                grid $base.cbtype$slop \
1019                    -in $base \
1020                    -sticky news \
1021                    -row $row \
1022                    -column $col \
1023                    -columnspan 1 \
1024                    -rowspan 1
1025                incr col
1026            }
1027            Label $base.cbfln$slop \
1028                -text $fln
1029            grid $base.cbfln$slop \
1030                -in $base \
1031                -sticky news \
1032                -row $row \
1033                -column $col \
1034                -columnspan 1 \
1035                -rowspan 1
1036            incr col
1037        }
1038        checkbutton $base.cbskip$slop \
1039            -variable ::ImportExport::wizard::Cols($fch,skip)
1040        grid $base.cbskip$slop \
1041            -in $base \
1042            -sticky news \
1043            -row $row \
1044            -column $col \
1045            -columnspan 1 \
1046            -rowspan 1
1047        incr row
1048    }
1049
1050    pack $base_.fgrid \
1051        -in $base_ \
1052        -side top \
1053        -expand 1 \
1054        -fill both
1055
1056}; # end proc ::ImportExport::wizard::add_step_table
1057
1058
1059#----------------------------------------------------------
1060#----------------------------------------------------------
1061#
1062proc ::ImportExport::wizard::add_step_finish {base_} {
1063
1064    global CurrentDB
1065
1066    variable ::ImportExport::exim
1067    variable ::ImportExport::eximtext
1068    variable ::ImportExport::tablename
1069    variable ::ImportExport::filename
1070
1071    variable Win
1072
1073    variable start_file_line
1074    variable stop_file_line
1075    variable progbar 0
1076    variable createtable
1077    variable line_count
1078
1079    # import line count is the lines the user tells us, export is all table row
1080    if {$exim} {
1081        set line_count [expr {$stop_file_line - $start_file_line + 1}]
1082    } else {
1083        set sql "
1084            SELECT COUNT(*)
1085              FROM $tablename"
1086        set res [wpg_exec $CurrentDB $sql]
1087        set line_count [lindex [pg_result $res -getTuple 0] 0]
1088        if {!$line_count} {set line_count 1}
1089        pg_result $res -clear
1090    }
1091
1092    frame $base_.frverytop
1093    # couple of import only checkbuttons
1094    if {$exim} {
1095        checkbutton $base_.frverytop.cbtrans \
1096            -variable ::ImportExport::wizard::transblock \
1097            -text [intlmsg {Perform operation in single TRANSACTION block ?}]
1098        pack $base_.frverytop.cbtrans \
1099            -in $base_.frverytop
1100        # if the table exists, should it be truncated
1101        if {!$createtable} {
1102        checkbutton $base_.frverytop.cbtrunc \
1103            -variable ::ImportExport::wizard::truncate \
1104            -text [intlmsg {TRUNCATE table before import ?}]
1105        pack $base_.frverytop.cbtrunc \
1106            -in $base_.frverytop
1107        }
1108    # for exporting, check to see if file should be clobbered, default is no
1109    } else {
1110        if {[file exists $filename]} {
1111            checkbutton $base_.frverytop.cbover \
1112                -variable ::ImportExport::wizard::overwrite \
1113                -text [intlmsg {Overwrite destination file ?}]
1114            pack $base_.frverytop.cbover \
1115                -in $base_.frverytop
1116        }
1117    }
1118
1119    frame $base_.frtop
1120    Button $base_.frtop.bexim \
1121        -text $eximtext \
1122        -borderwidth 2 \
1123        -command {::ImportExport::wizard::step_finish_perform}
1124    ProgressBar $base_.frtop.progbar \
1125        -variable ::ImportExport::wizard::progbar \
1126        -maximum $line_count \
1127        -borderwidth 1 \
1128        -relief sunken
1129
1130    frame $base_.frbot
1131    set Win(errortext) $base_.frbot.terr
1132    set Win(errorxscroll) $base_.frbot.xscroll
1133    set Win(erroryscroll) $base_.frbot.yscroll
1134    scrollbar $base_.frbot.xscroll \
1135        -borderwidth 1 \
1136        -command [subst {$Win(errortext) xview}] \
1137        -orient horiz \
1138        -width 10
1139    scrollbar $base_.frbot.yscroll \
1140        -borderwidth 1 \
1141        -command [subst {$Win(errortext) yview}] \
1142        -orient vert \
1143        -width 10
1144    text $base_.frbot.terr \
1145        -width 50 \
1146        -height 13 \
1147        -borderwidth 1 \
1148        -wrap word \
1149        -xscrollcommand [subst {$Win(errorxscroll) set}] \
1150        -yscrollcommand [subst {$Win(erroryscroll) set}]
1151
1152    pack $base_.frverytop \
1153        -in $base_ \
1154        -side top \
1155        -expand 1 \
1156        -fill both
1157
1158    pack $base_.frtop.bexim \
1159        -in $base_.frtop \
1160        -side left
1161    pack $base_.frtop.progbar \
1162        -in $base_.frtop \
1163        -side left \
1164        -expand 1 \
1165        -fill both
1166    pack $base_.frtop \
1167        -in $base_ \
1168        -side top \
1169        -expand 1 \
1170        -fill both
1171
1172    # grid columnconf $base_.frbot 0 \
1173    #    -weight 1
1174    # grid rowconf $base_.frbot 0 \
1175    #    -weight 1
1176    grid $base_.frbot.xscroll \
1177        -in $base_.frbot \
1178        -column 0 \
1179        -row 1 \
1180        -columnspan 1 \
1181        -rowspan 1 \
1182        -sticky we
1183    grid $base_.frbot.yscroll \
1184        -in $base_.frbot \
1185        -column 1 \
1186        -row 0 \
1187        -columnspan 1 \
1188        -rowspan 1 \
1189        -sticky sn
1190    grid $base_.frbot.terr \
1191        -in $base_.frbot \
1192        -column 0 \
1193        -row 0 \
1194        -columnspan 1 \
1195        -rowspan 1 \
1196        -sticky news
1197    pack $base_.frbot \
1198        -in $base_ \
1199        -side top \
1200        -expand 1 \
1201        -fill both
1202
1203}; # end proc ::ImportExport::wizard::add_step_finish
1204
1205
1206#----------------------------------------------------------
1207#----------------------------------------------------------
1208#
1209proc ::ImportExport::wizard::step_finish_errormsg {msg_} {
1210
1211    variable Win
1212
1213    $Win(errortext) insert end "$msg_\n"
1214    $Win(errortext) see end
1215
1216    # this flushes all pending display events
1217    # and lets us see the error log window plus the progress bar
1218    update idletasks
1219
1220}; # end proc ::ImportExport::wizard::step_finish_errormsg
1221
1222
1223#----------------------------------------------------------
1224#----------------------------------------------------------
1225#
1226proc ::ImportExport::wizard::step_finish_perform {} {
1227
1228    global CurrentDB
1229    global PgAcVar
1230
1231    variable Win
1232    variable Cols
1233
1234    variable ::ImportExport::exim
1235    variable ::ImportExport::filename
1236    variable ::ImportExport::tablename
1237    variable ::ImportExport::delimiter
1238    variable ::ImportExport::nullas
1239
1240    variable colhdr
1241    variable decoration
1242    variable row_head
1243    variable row_foot
1244    variable page_head
1245    variable page_foot
1246    variable filecolhdrs
1247    variable tablecols
1248    variable start_file_line
1249    variable stop_file_line
1250    variable progbar 0
1251    variable transblock
1252    variable truncate
1253    variable overwrite
1254    variable createtable
1255
1256    variable buf
1257
1258    set eximfailed 0
1259
1260    # set the tab
1261    if {$delimiter=="TAB"} {
1262        set delimiter "\x09"
1263    }
1264    # set the whitespace
1265    if {$delimiter=="WHITESPACE"} {
1266        set delimiter " "
1267    }
1268
1269    set timestart [clock clicks]
1270    setCursor CLOCK
1271
1272    # take care of the importing first
1273    if {$exim} {
1274
1275        set msg [intlmsg {Starting import}]
1276        ::ImportExport::wizard::step_finish_errormsg "$msg: $filename..."
1277
1278        # do we need to create a table
1279        if {$createtable} {
1280            set sql "CREATE TABLE $tablename ("
1281            foreach fch $filecolhdrs {
1282                if {!$Cols($fch,skip)} {
1283                    append sql "\"$Cols($fch,name)\" $Cols($fch,type),"
1284                }
1285            }
1286            set sql [string trimright $sql ,]
1287            append sql ")"
1288            set msg [intlmsg {Creating table}]
1289            ::ImportExport::wizard::step_finish_errormsg "$msg: $tablename..."
1290            sql_exec noquiet $sql
1291        # the table exists but should be we truncate it
1292        } elseif {[info exists truncate] && $truncate} {
1293            set sql "TRUNCATE TABLE $tablename"
1294            set msg [intlmsg {Truncating table}]
1295            ::ImportExport::wizard::step_finish_errormsg "$msg: $tablename..."
1296            sql_exec noquiet $sql
1297        }
1298
1299        # if we are doing this in one transaction block start it now
1300        if {$transblock} {
1301            wpg_exec $CurrentDB "BEGIN TRANSACTION"
1302            pg_result $PgAcVar(pgsql,res) -clear
1303        }
1304
1305        # open the file
1306        set fid [::open "$filename" r]
1307
1308        # keep reading lines until end of file
1309        for {set row 1} {![eof $fid] && $row<=$stop_file_line} {incr row} {
1310
1311            # get one file line and split it up
1312            set bufcnt [gets $fid buf]
1313
1314            # make sure we start on the right line
1315            if {$row>=$start_file_line} {
1316
1317                set progbar [expr {$row - $start_file_line + 1}]
1318
1319                # really handy for HTML table imports
1320                set buf [string trimleft $buf $row_head]
1321                set buf [string trimright $buf $row_foot]
1322
1323                set delimbuf [::csv::split $buf $delimiter]
1324
1325                # special check for whitespace
1326                if {[string length [string trim $delimiter]]==0} {
1327                    set blankbuf [list]
1328                    foreach l $delimbuf {
1329                        if {[string length [string trim $l]]>0} {
1330                            lappend blankbuf $l
1331                        }
1332                    }
1333                    set delimbuf $blankbuf
1334                }
1335
1336                set decorbuf [list]
1337
1338                # pretty it up
1339                foreach l $delimbuf {
1340                    if {[string match $nullas $l]} {
1341                        lappend decorbuf $nullas
1342                    } else {
1343                        lappend decorbuf [string trim $l $decoration]
1344                    }
1345                }
1346
1347                # create the insert line
1348                set fvals ""
1349                set tcols ""
1350
1351                foreach f $decorbuf t $filecolhdrs {
1352                    if {[info exists Cols($t,skip)] && !$Cols($t,skip)} {
1353                        append tcols "\"$Cols($t,name)\","
1354                        if {[string match $nullas $f]} {
1355                            append fvals "NULL,"
1356                        } else {
1357                            regsub -all {\'} $f {\\'} ff
1358                            regsub -all {\"} $ff {\\"} fff
1359                            append fvals "'$fff',"
1360                        }
1361                    }
1362                }
1363
1364                set tcols [string trimright $tcols ,]
1365                set fvals [string trimright $fvals ,]
1366                set sql "INSERT INTO $tablename ($tcols)
1367                              VALUES ($fvals)"
1368
1369                # start the insert transaction
1370                # we are doing a ton of work here and need to keep clean
1371                if {!$transblock} {
1372                    wpg_exec $CurrentDB "BEGIN TRANSACTION"
1373                    pg_result $PgAcVar(pgsql,res) -clear
1374                }
1375
1376                wpg_exec $CurrentDB $sql
1377
1378                if {$PgAcVar(pgsql,status)=="PGRES_COMMAND_OK"} {
1379                    pg_result $PgAcVar(pgsql,res) -clear
1380                    if {!$transblock} {
1381                        wpg_exec $CurrentDB "COMMIT TRANSACTION"
1382                        pg_result $PgAcVar(pgsql,res) -clear
1383                    }
1384                } else {
1385                    set errmsg [intlmsg "ERROR"]
1386                    append errmsg ": " [pg_result $PgAcVar(pgsql,res) -error]
1387                    pg_result $PgAcVar(pgsql,res) -clear
1388                    ::ImportExport::wizard::step_finish_errormsg "$errmsg"
1389                    set badmsg [intlmsg "BAD ROW"]
1390                    ::ImportExport::wizard::step_finish_errormsg "$badmsg #$row"
1391                    ::ImportExport::wizard::step_finish_errormsg "SQL: $sql"
1392                    wpg_exec $CurrentDB "ROLLBACK TRANSACTION"
1393                    pg_result $PgAcVar(pgsql,res) -clear
1394                    if {$transblock} {
1395                        set eximfailed 1
1396                        break
1397                    }
1398                }
1399            }
1400        }
1401
1402        # close the file
1403        ::close $fid
1404
1405        # this is if we were working within one large transaction block
1406        if {$transblock && $PgAcVar(pgsql,status)=="PGRES_COMMAND_OK"} {
1407            wpg_exec $CurrentDB "COMMIT TRANSACTION"
1408            pg_result $PgAcVar(pgsql,res) -clear
1409        }
1410
1411        setCursor NORMAL
1412        set timestop [clock clicks]
1413        set timediff [expr {double($timestop-$timestart)/double(1000000)}]
1414
1415        if {$eximfailed} {
1416            set msg [intlmsg {Import failed, no rows imported.}]
1417            ::ImportExport::wizard::step_finish_errormsg "$msg"
1418        } else {
1419            set msg [intlmsg {Finished import}]
1420            set msg2 [intlmsg {rows}]
1421            set total_rows [expr {$row - $start_file_line}]
1422            ::ImportExport::wizard::step_finish_errormsg "$msg: $total_rows $msg2 in $timediff sec."
1423        }
1424
1425    #
1426    # okay export should be a lot easier
1427    #
1428    } else {
1429
1430        set msg [intlmsg {Starting export}]
1431        ::ImportExport::wizard::step_finish_errormsg "$msg: $filename..."
1432
1433        # figure out what columns were skipped, if any
1434        set tcols [list]
1435        set ttcols [list]
1436        foreach t $tablecols {
1437            if {[info exists Cols($t,skip)] && !$Cols($t,skip)} {
1438                lappend tcols $t
1439                lappend ttcols "t1.\"$t\""
1440            }
1441        }
1442
1443        set sql "SELECT [join $ttcols ,]
1444                   FROM $tablename t1"
1445
1446        set openmode ""
1447        if {[info exists overwrite] && $overwrite} {
1448            set openmode "w"
1449        } else {
1450            set openmode "a"
1451        }
1452        set fid [::open "$filename" $openmode]
1453
1454        set row 0
1455
1456        set timestart [clock clicks]
1457        setCursor CLOCK
1458
1459        # see if we have a page header
1460        if {$page_head!=""} {
1461            puts $fid $page_head
1462        }
1463
1464        # check whether we are letting column names be first row of file
1465        if {$colhdr} {
1466            set line $row_head
1467            foreach t $tcols {
1468                append line $decoration $t $decoration $delimiter
1469            }
1470            set line [string trimright $line $delimiter]
1471            append line $row_foot
1472            puts $fid $line
1473        }
1474
1475        wpg_select $CurrentDB $sql rec {
1476            set progbar [expr {$row+1}]
1477            set line $row_head
1478            foreach t $tcols {
1479                append line $decoration $rec($t) $decoration $delimiter
1480            }
1481            set line [string trimright $line $delimiter]
1482            append line $row_foot
1483            puts $fid $line
1484            incr row
1485        }
1486
1487        # see if we have a page footer
1488        if {$page_foot!=""} {
1489            puts $fid $page_foot
1490        }
1491
1492        ::close $fid
1493
1494        setCursor NORMAL
1495        set timestop [clock clicks]
1496        set timediff [expr {double($timestop-$timestart)/double(1000000)}]
1497
1498        set msg [intlmsg {Finished export}]
1499        set msg2 [intlmsg {rows}]
1500        ::ImportExport::wizard::step_finish_errormsg "$msg: $row $msg2 in $timediff sec."
1501
1502    }; # end if
1503
1504}; # end proc ::ImportExport::wizard::step_finish_perform
1505
1506
1507#----------------------------------------------------------
1508#----------------------------------------------------------
1509#
1510proc ::ImportExport::wizard::step_file_redraw {} {
1511
1512    setCursor CLOCK
1513
1514    variable Win
1515
1516    variable ::ImportExport::exim
1517    variable ::ImportExport::filename
1518
1519    variable start_file_line
1520    variable stop_file_line
1521    variable colhdr
1522    variable filecolhdrs
1523
1524    # this proc doesnt apply to exporting
1525    if {!$exim} {
1526        return
1527    }
1528
1529    # set the tablelist to the first 10 lines of the file
1530    set base $Win(step_file_tablelist)
1531
1532    $base.tlfile delete 0 end
1533
1534    set lbuf {}
1535    set fid [::open "$filename" r]
1536    for {set i 1} {$i<=[expr {10+$start_file_line}] && ![eof $fid]} {incr i} {
1537        set bufcnt [gets $fid buf]
1538        if {$i>=$start_file_line} {
1539            lappend lbuf [parse_lof $buf]
1540        }
1541
1542    }
1543    ::close $fid
1544
1545    set colhdrs [list]
1546    set filecolhdrs [list]
1547    set c 0
1548    foreach col [lindex $lbuf 0] {
1549        incr c
1550        if {$colhdr} {
1551            lappend colhdrs 0 $col left
1552            lappend filecolhdrs $col
1553        } else {
1554            lappend colhdrs 0 column$c left
1555            lappend filecolhdrs column$c
1556        }
1557    }
1558
1559    $base.tlfile configure -columns $colhdrs
1560    if {$colhdr} {
1561        set lbuf [lrange $lbuf 1 end]
1562    }
1563
1564    foreach l $lbuf {
1565        $base.tlfile insert end $l
1566    }
1567
1568    if {$start_file_line==0 || $stop_file_line==0} {
1569        # set the scrollbars' ranges to the line count
1570        set linecnt 0
1571        ::fileutil::foreachLine linevar $filename {incr linecnt}
1572        set sbbase $Win(step_file_grid)
1573        $sbbase.sbstart configure -range [subst {1 $linecnt 1}]
1574        $sbbase.sbstop configure -range [subst {1 $linecnt 1}]
1575        $sbbase.sbstart setvalue first
1576        $sbbase.sbstop setvalue last
1577    }
1578
1579    setCursor NORMAL
1580
1581}; # end proc ::ImportExport::wizard::step_file_redraw
1582
1583
1584#----------------------------------------------------------
1585# ::ImportExport::wizard::parse_lof --
1586#
1587#   parses one line of a file w/decorations, delims, etc.
1588#----------------------------------------------------------
1589#
1590proc ::ImportExport::wizard::parse_lof {lof_} {
1591
1592    variable ::ImportExport::delimiter
1593    variable ::ImportExport::nullas
1594
1595    variable decoration
1596    variable row_head
1597    variable row_foot
1598
1599    set delimbuf [::csv::split $lof_ $delimiter]
1600
1601    # gank the row header and footer
1602    set delimbuf [string trimleft $delimbuf $row_head]
1603    set delimbuf [string trimright $delimbuf $row_foot]
1604
1605    # special check for whitespace
1606    if {[string length [string trim $delimiter]]==0} {
1607        set blankbuf [list]
1608        foreach l $delimbuf {
1609            if {[string length [string trim $l]]>0} {
1610                lappend blankbuf $l
1611            }
1612        }
1613        set delimbuf $blankbuf
1614    }
1615
1616    set decorbuf {}
1617    foreach l $delimbuf {
1618        if {[string match $nullas $l]} {
1619            lappend decorbuf [intlmsg {NULL}]
1620        } else {
1621            lappend decorbuf [string trim $l $decoration]
1622        }
1623    }
1624
1625    return $decorbuf
1626
1627}; # end proc ::ImportExport::wizard::parse_lof
1628
1629
1630#----------------------------------------------------------
1631# ::ImportExport::wizard::set_presets --
1632#
1633#   handles changing default file formatting characters
1634#----------------------------------------------------------
1635#
1636proc ::ImportExport::wizard::set_presets {} {
1637
1638    variable presets
1639    variable page_head
1640    variable page_foot
1641    variable row_head
1642    variable row_foot
1643    variable decoration
1644    variable ::ImportExport::nullas
1645    variable ::ImportExport::delimiter
1646
1647    switch $presets {
1648
1649        CSV {
1650            set page_head ""
1651            set page_foot ""
1652            set row_head ""
1653            set row_foot ""
1654            set decoration "\""
1655            set delimiter ","
1656            set nullas "\x00"
1657        }
1658
1659        HTML {
1660            set page_head "<table>"
1661            set page_foot "</table>"
1662            set row_head "<tr><td>"
1663            set row_foot "</td></tr>"
1664            set decoration ""
1665            set delimiter "</td><td>"
1666            set nullas ""
1667        }
1668
1669        WHITESPACE {
1670            set page_head ""
1671            set page_foot ""
1672            set row_head ""
1673            set row_foot ""
1674            set decoration ""
1675            set delimiter " "
1676            set nullas "\x00"
1677        }
1678
1679        # default is tab
1680        default {
1681            set page_head ""
1682            set page_foot ""
1683            set row_head ""
1684            set row_foot ""
1685            set decoration ""
1686            set delimiter "TAB"
1687            set nullas "\x00"
1688        }
1689
1690    }
1691
1692}; # end proc ::ImportExport::wizard::set_presets
1693
1694
1695### END ImportExport::wizard NAMESPACE ###
1696### BEGIN Visual Tcl code ###
1697
1698
1699
1700proc vTclWindow.pgaw:ImportExport {base} {
1701    if {$base == ""} {
1702        set base .pgaw:ImportExport
1703    }
1704    if {[winfo exists $base]} {
1705        wm deiconify $base; return
1706    }
1707    toplevel $base -class Toplevel
1708    wm focusmodel $base passive
1709    wm geometry $base 335x180+259+304
1710    wm maxsize $base 1280 1024
1711    wm minsize $base 1 1
1712    wm overrideredirect $base 0
1713    wm resizable $base 0 0
1714    wm title $base [intlmsg "Import-Export table"]
1715
1716    # some helpful key bindings
1717    bind $base <Control-Key-w> [subst {destroy $base}]
1718
1719    label $base.l1  -borderwidth 0 -text [intlmsg {Table name}]
1720    entry $base.e1  -background #fefefe -borderwidth 1 \
1721        -textvariable ::ImportExport::tablename
1722    label $base.l2  -borderwidth 0 -text [intlmsg {File name}]
1723    entry $base.e2  -background #fefefe -borderwidth 1 \
1724        -textvariable ::ImportExport::filename
1725    button $base.browsebtn  -borderwidth 1 -text [intlmsg Browse] -command {
1726        set types {
1727            {{Text Files}    {.txt}}
1728            {{All Files}    *}
1729        }
1730        if {[.pgaw:ImportExport.expbtn cget -text]=="Import"} {
1731            set tkget "tk_getOpenFile"
1732        } else {
1733            set tkget "tk_getSaveFile"
1734        }
1735        if {[catch {$tkget -defaultextension .txt -filetypes $types \
1736            -title [.pgaw:ImportExport.expbtn cget -text]} \
1737            ::ImportExport::filename] || \
1738            [string match {} $::ImportExport::filename]} return
1739    }
1740    label $base.l3  -borderwidth 0 -text [intlmsg {Field delimiter}]
1741    entry $base.e3  -background #fefefe -borderwidth 1 \
1742        -textvariable ::ImportExport::delimiter
1743    label $base.lnullas  -borderwidth 0 -text [intlmsg {Nulls As}]
1744    entry $base.enullas  -background #fefefe -borderwidth 1 \
1745        -textvariable ::ImportExport::nullas
1746    button $base.expbtn  -borderwidth 1 -text [intlmsg Export] \
1747        -command {
1748            ImportExport::execute
1749            Window destroy .pgaw:ImportExport
1750        }
1751    button $base.cancelbtn  -borderwidth 1 \
1752        -command {Window destroy .pgaw:ImportExport} -text [intlmsg Cancel]
1753    checkbutton $base.oicb  -borderwidth 1  \
1754        -text [intlmsg {with OIDs}] -variable ::ImportExport::withoids
1755
1756    Button $base.wizbtn \
1757        -helptext [intlmsg {Wizard}] \
1758        -image ::icon::wizard-22 \
1759        -borderwidth 2 \
1760        -command {
1761            setCursor CLOCK
1762            Window destroy .pgaw:ImportExport
1763            ::ImportExport::wizard::start_tkwizard
1764            setCursor NORMAL
1765        }
1766
1767    place $base.l1  -x 15 -y 15 -anchor nw -bordermode ignore
1768    place $base.e1  -x 115 -y 10 -height 22 -anchor nw -bordermode ignore
1769    place $base.l2  -x 15 -y 45 -anchor nw -bordermode ignore
1770    place $base.e2  -x 115 -y 40 -height 22 -anchor nw -bordermode ignore
1771    place $base.browsebtn  -x 265 -y 40 -height 25 -width 60 \
1772        -anchor nw -bordermode ignore
1773    place $base.l3  -x 15 -y 75 -height 18 -anchor nw -bordermode ignore
1774    place $base.e3  -x 115 -y 74 -width 33 -height 22 \
1775        -anchor nw -bordermode ignore
1776    place $base.lnullas  -x 15 -y 105 -height 18 -anchor nw -bordermode ignore
1777    place $base.enullas  -x 115 -y 104 -width 33 -height 22 \
1778        -anchor nw -bordermode ignore
1779    place $base.expbtn  -x 60 -y 140 -height 25 -width 75 \
1780        -anchor nw -bordermode ignore
1781    place $base.cancelbtn  -x 155 -y 140 -height 25 -width 75 \
1782        -anchor nw -bordermode ignore
1783    place $base.oicb  -x 170 -y 105 -anchor nw -bordermode ignore
1784    place $base.wizbtn -x 260 -y 90 -height 60 -width 60 -anchor nw
1785
1786}
1787
1788
1789