1 /* fileviewerbg.cc
2  * This file belongs to Worker, a file manager for UN*X/X11.
3  * Copyright (C) 2010-2017 Ralf Hoffmann.
4  * You can contact me at: ralf@boomerangsworld.de
5  *   or http://www.boomerangsworld.de/worker
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #include "fileviewerbg.hh"
23 #include "fileviewer.hh"
24 #include "worker.h"
25 #include "aguix/textview.h"
26 #include "textstoragefile.h"
27 #include "nwc_fsentry.hh"
28 #include "aguix/util.h"
29 #include "aguix/refcount.hh"
30 #include "filenameshrinker.hh"
31 #include "aguix/searchtextstorage.hh"
32 #include "aguix/backgroundmessagehandler.hh"
33 #include "aguix/choosebutton.h"
34 #include "aguix/button.h"
35 #include "aguix/stringgadget.h"
36 #include "worker_locale.h"
37 #include "wconfig.h"
38 #include "listermode.h"
39 #include "virtualdirmode.hh"
40 #include "pdatei.h"
41 
FileViewerBG(Worker * worker)42 FileViewerBG::FileViewerBG( Worker *worker ) : win( NULL ),
43                                                m_wrap_mode( false ),
44                                                m_showlinenumbers_mode( false ),
45                                                ts( NULL ),
46                                                tv( NULL ),
47                                                search_sg( NULL ),
48                                                okb( NULL ),
49                                                wcb( NULL ),
50                                                slncb( NULL ),
51                                                jumplineb( NULL ),
52                                                readmoreb( NULL ),
53                                                reloadb( NULL ),
54                                                m_next_match_b( NULL ),
55                                                m_prev_match_b( NULL ),
56                                                m_restart_search_b( NULL ),
57                                                m_showintab_b( NULL ),
58                                                m_find_pos_text( NULL ),
59                                                m_worker( worker )
60 {
61 }
62 
~FileViewerBG()63 FileViewerBG::~FileViewerBG()
64 {
65     m_destroy_callback = NULL;
66     if ( win != NULL ) delete win;
67     if ( ts != NULL ) delete ts;
68 }
69 
view(const std::list<std::string> & filelist,int initial_line_number,bool highlight_initial_line,RefCount<FileViewerDestroyCallback> destroy_callback)70 void FileViewerBG::view( const std::list<std::string> &filelist,
71                          int initial_line_number,
72                          bool highlight_initial_line,
73                          RefCount< FileViewerDestroyCallback > destroy_callback )
74 {
75     AGUIX *aguix = Worker::getAGUIX();
76     const int cfix = AContainer::ACONT_MINH +
77         AContainer::ACONT_MINW +
78         AContainer::ACONT_MAXH +
79         AContainer::ACONT_MAXW;
80     const int cincw = AContainer::ACONT_MINH +
81         AContainer::ACONT_MINW +
82         AContainer::ACONT_MAXH;
83     const int cincwnr = cincw +
84         AContainer::ACONT_NORESIZE;
85 
86     m_filelist = filelist;
87     m_destroy_callback = destroy_callback;
88 
89     ts = NULL;
90     tv = NULL;
91     std::list<std::string>::const_iterator it1;
92     int w, h, sw, sh;
93 
94     win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 1290 ) );
95     win->create();
96     /*  if ( aguix->getTransientWindow() != NULL ) {
97         win->setTransientForAWindow( aguix->getTransientWindow() );
98         }*/
99 
100     AContainer *ac1 = win->setContainer( new AContainer( win, 1, 4 ), true );
101     ac1->setMinSpace( 5 );
102     ac1->setMaxSpace( 5 );
103 
104     AContainer *ac1_1 = ac1->add( new AContainer( win, 4, 1 ), 0, 0 );
105     ac1_1->setMinSpace( 5 );
106     ac1_1->setMaxSpace( 5 );
107     ac1_1->setBorderWidth( 0 );
108     ac1_1->add( new Text( aguix, 0, 0, catalog.getLocale( 404 ) ), 0, 0, AContainer::CO_FIXNR );
109     Text *fnt = (Text*)ac1_1->add( new Text( aguix, 0, 0, "" ), 1, 0, AContainer::ACONT_MINH + AContainer::ACONT_MAXH );
110     readmoreb = (Button*)ac1_1->add( new Button( aguix, 0, 0, catalog.getLocale( 763 ), 0 ),
111                                      2, 0, cfix );
112     readmoreb->setBubbleHelpText( catalog.getLocale( 1146 ) );
113 
114     reloadb = ac1_1->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 511 ), 0 ),
115                                 3, 0, cfix );
116     reloadb->setBubbleHelpText( catalog.getLocale( 1175 ) );
117 
118     fnt->setTextShrinker( RefCount<TextShrinker>( new FileNameShrinker() ) );
119 
120     it1 = filelist.begin();
121 
122     RefCount<AFontWidth> lencalc( new AFontWidth( aguix, aguix->getFont( wconfig->getFont( 4 ).c_str() ) ) );
123 
124     if ( buildTextView( *it1, ac1, fnt, lencalc ) != 0 ) {
125         delete win;
126 	win = NULL;
127         if ( ts != NULL ) delete ts;
128 	ts = NULL;
129         return;
130     }
131 
132     ac1->readLimits();
133     ac1_1->readLimits();
134 
135     AContainer *ac1_3 = ac1->add( new AContainer( win, 6, 1 ), 0, 3 );
136     ac1_3->setMinSpace( 5 );
137     ac1_3->setMaxSpace( -1 );
138     ac1_3->setBorderWidth( 0 );
139 
140     /*nextb = (Button*)ac1_3->add( new Button( aguix, 0, 0, "Next", 1, 0, 2 ),
141       0, 0, cfix );
142       prevb = (Button*)ac1_3->add( new Button( aguix, 0, 0, "Prev", 1, 0, 2 ),
143       1, 0, cfix );*/
144     wcb = (ChooseButton*)ac1_3->add( new ChooseButton( aguix, 0, 0,
145                                                        m_wrap_mode, catalog.getLocale( 637 ),
146                                                        LABEL_RIGHT, 0 ),
147                                      0, 0, cincwnr );
148     wcb->setBubbleHelpText( catalog.getLocale( 1147 ) );
149     slncb = (ChooseButton*)ac1_3->add( new ChooseButton( aguix, 0, 0,
150                                                          m_showlinenumbers_mode, catalog.getLocale( 715 ),
151                                                          LABEL_RIGHT, 0 ),
152                                        1, 0, cincwnr );
153     slncb->setBubbleHelpText( catalog.getLocale( 1148 ) );
154 
155     snp_cb = ac1_3->addWidget( new ChooseButton( aguix, 0, 0,
156                                                  false, catalog.getLocale( 1176 ),
157                                                  LABEL_RIGHT, 0 ),
158                                2, 0, cincwnr );
159     snp_cb->setBubbleHelpText( catalog.getLocale( 1177 ) );
160 
161     jumplineb = (Button*)ac1_3->add( new Button( aguix, 0, 0, catalog.getLocale( 716 ), 2 ),
162                                      3, 0, cfix );
163     jumplineb->setBubbleHelpText( catalog.getLocale( 1142 ) );
164 
165     m_showintab_b = ac1_3->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 1178 ), 2 ),
166                                       4, 0, cfix );
167     m_showintab_b->setBubbleHelpText( catalog.getLocale( 1179 ) );
168 
169     okb = (Button*)ac1_3->add( new Button( aguix, 0, 0, catalog.getLocale( 633 ), 2 ),
170                                5, 0, cfix );
171     okb->setBubbleHelpText( catalog.getLocale( 1143 ) );
172 
173     AContainer *ac1_4 = ac1->add( new AContainer( win, 5, 1 ), 0, 2 );
174     ac1_4->setMinSpace( 5 );
175     ac1_4->setMaxSpace( 10 );
176     ac1_4->setBorderWidth( 0 );
177 
178     AContainer *ac1_4_1 = ac1_4->add( new AContainer( win, 2, 1 ), 0, 0 );
179     ac1_4_1->setMinSpace( 5 );
180     ac1_4_1->setMaxSpace( 5 );
181     ac1_4_1->setBorderWidth( 0 );
182 
183     ac1_4_1->add( new Text( aguix, 0, 0, catalog.getLocale( 790 ) ), 0, 0, AContainer::CO_FIXNR + AContainer::ACONT_CENTER );
184     search_sg = (StringGadget*)ac1_4_1->add( new StringGadget( aguix, 0, 0, 60, "", 1 ),
185                                              1, 0, cincw );
186     search_sg->setBubbleHelpText( catalog.getLocale( 1149 ) );
187 
188     m_next_match_b = ac1_4->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 1136 ), 2 ),
189                                        1, 0, cfix );
190     m_next_match_b->setBubbleHelpText( catalog.getLocale( 1144 ) );
191     m_prev_match_b = ac1_4->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 1137 ), 2 ),
192                                        2, 0, cfix );
193     m_prev_match_b->setBubbleHelpText( catalog.getLocale( 1145 ) );
194     m_restart_search_b = ac1_4->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 1138 ), 2 ),
195                                            3, 0, cfix );
196 
197     AContainer *ac1_4_2 = ac1_4->add( new AContainer( win, 2, 1 ), 4, 0 );
198     ac1_4_2->setMinSpace( 5 );
199     ac1_4_2->setMaxSpace( 5 );
200     ac1_4_2->setBorderWidth( 0 );
201 
202     ac1_4_2->addWidget( new Text( aguix, 0, 0, catalog.getLocale( 1139 ) ), 0, 0, AContainer::CO_FIX );
203     m_find_pos_text = ac1_4_2->addWidget( new Text( aguix, 0, 0, catalog.getLocale( 1140 ) ),
204                                           1, 0, AContainer::CO_INCW );
205     {
206         std::string info = AGUIXUtils::formatStringToString( catalog.getLocale( 1141 ), 1000000000 );
207         int tw = aguix->getTextWidth( info.c_str() );
208 
209         if ( tw > m_find_pos_text->getWidth() ) {
210             m_find_pos_text->resize( tw, m_find_pos_text->getHeight() );
211             ac1_4_2->readLimits();
212         }
213     }
214 
215     win->setDoTabCycling( true );
216     win->contMaximize( true );
217 
218     w = win->getWidth();
219     h = win->getHeight();
220 
221     int rx, ry, rw, rh;
222 
223     aguix->getLargestDimensionOfCurrentScreen( &rx, &ry,
224                                                &rw, &rh );
225 
226     sw = rw;
227     sh = rh;
228     sw = (int)( (double)sw * 0.8 );
229     sh = (int)( (double)sh * 0.8 );
230     if ( sw < 200 ) sw = 200;
231     if ( sh < 100 ) sh = 100;
232     if ( w < sw ) w = sw;
233     if ( h < sh ) h = sh;
234     win->resize( w, h );
235 
236     tv->setLineWrap( wcb->getState() );
237     tv->setShowLineNumbers( slncb->getState() );
238     tv->jumpToLine( initial_line_number, highlight_initial_line );
239 
240     if ( ts->incompleteFile() == false ) {
241         readmoreb->hide();
242     }
243 
244     m_find_pos_text->setText( "" );
245 
246     win->useStippleBackground();
247     win->centerScreen();
248     win->show();
249 
250     win->applyFocus( tv );
251 }
252 
handleAGUIXMessage(AGMessage & msg)253 void FileViewerBG::handleAGUIXMessage( AGMessage &msg )
254 {
255     AGUIX *aguix = Worker::getAGUIX();
256     int endmode = -1;
257     //  bool ignore_key_release = true;
258 
259     switch ( msg.type ) {
260         case AG_CLOSEWINDOW:
261             if ( msg.closewindow.window == win->getWindow() ) {
262                 endmode = 0;
263             }
264             break;
265         case AG_CHOOSECLICKED:
266             if ( msg.choose.button == wcb ) {
267                 tv->setLineWrap( msg.choose.state );
268             } else if ( msg.choose.button == slncb ) {
269                 tv->setShowLineNumbers( msg.choose.state );
270             } else if ( msg.choose.button == snp_cb ) {
271                 if ( msg.choose.state ) {
272                     ts->setConvertMode( TextStorageString::CONVERT_NON_PRINTABLE_HEX );
273                 } else {
274                     ts->setConvertMode( TextStorageString::CONVERT_NON_PRINTABLE_SIMPLE );
275                 }
276                 tv->textStorageChanged();
277             }
278             break;
279         case AG_BUTTONCLICKED:
280             if ( msg.button.button == okb ) {
281                 endmode = 0;
282                 /*	  } else if ( msg.button.button == nextb ) {
283                           it1++;
284                           if ( it1 == filelist.end() ) it1 = filelist.begin();
285                           buildTextView( *it1, &ts, &tv, ac1 );
286                           } else if ( msg.button.button == prevb ) {
287                           if ( it1 == filelist.begin() )
288                           it1 = filelist.end();
289                           it1--;
290                           buildTextView( *it1, &ts, &tv, ac1 );*/
291             } else if ( msg.button.button == jumplineb ) {
292                 jumpToLine();
293             } else if ( msg.button.button == readmoreb ) {
294                 ts->readMore();
295                 tv->textStorageChanged();
296                 if ( ts->incompleteFile() == false ) {
297                     readmoreb->hide();
298                 }
299             } else if ( msg.button.button == reloadb ) {
300                 ts->reloadFile();
301                 tv->textStorageChanged();
302                 if ( ts->incompleteFile() == false ) {
303                     readmoreb->hide();
304                 }
305             } else if ( msg.button.button == m_next_match_b ) {
306                 nextMatch();
307             } else if ( msg.button.button == m_prev_match_b ) {
308                 nextMatch( true );
309             } else if ( msg.button.button == m_restart_search_b ) {
310                 restartSearchFromTop();
311             } else if ( msg.button.button == m_showintab_b ) {
312                 showInWorkerTab();
313             }
314             break;
315             /*        case AG_KEYPRESSED:
316                       ignore_key_release = false;
317                       break;*/
318 	case AG_KEYPRESSED:
319             if ( /*ignore_key_release == false && */win->isParent( msg.key.window, false ) == true ) {
320                 switch ( msg.key.key ) {
321                     case XK_q:
322                     case XK_F3:
323                     case XK_F10:
324                         endmode = 0;
325                         break;
326                     case XK_l:
327                         if ( ( msg.key.keystate & ( ControlMask | Mod1Mask ) ) != 0 ) {
328                             jumpToLine();
329                         } else if ( KEYSTATEMASK( msg.key.keystate ) == 0 &&
330                                     ! tv->getHasFocus() ) {
331                             tv->setShowLineNumbers( ( tv->getShowLineNumbers() == true ) ? false : true );
332                         }
333                         break;
334                     case XK_w:
335                         if ( KEYSTATEMASK( msg.key.keystate ) == 0 &&
336                              ! tv->getHasFocus() ) {
337                             tv->setLineWrap( ( tv->getLineWrap() == true ) ? false : true );
338                         }
339                         break;
340                     case XK_r:
341                         if ( ( msg.key.keystate & ( ControlMask | Mod1Mask ) ) != 0 ) {
342                             ts->reloadFile();
343                             tv->textStorageChanged();
344                             if ( ts->incompleteFile() == false ) {
345                                 readmoreb->hide();
346                             }
347                         } else {
348                             if ( ts->incompleteFile() == true ) {
349                                 ts->readMore();
350                                 tv->textStorageChanged();
351                                 if ( ts->incompleteFile() == false ) {
352                                     readmoreb->hide();
353                                 }
354                             }
355                         }
356                         break;
357                     case XK_slash:
358                         if ( search_sg->isActive() == true ) {
359                             nextMatch();
360                         } else {
361                             std::pair<int, int> rl = ts->getRealLinePair( tv->getYOffset() );
362                             ts_search->setSearchStartLine( rl.first );
363                             search_sg->setText( "" );
364                             search_sg->activate();
365                         }
366                         break;
367                     case XK_s:
368                     case XK_f:
369                     case XK_i:
370                         if ( ( msg.key.keystate & ( ControlMask | Mod1Mask ) ) != 0 ) {
371                             if ( search_sg->isActive() == true ) {
372                                 nextMatch();
373                             } else {
374                                 std::pair<int, int> rl = ts->getRealLinePair( tv->getYOffset() );
375                                 ts_search->setSearchStartLine( rl.first );
376                                 search_sg->setText( "" );
377                                 search_sg->activate();
378                             }
379                         }
380                         break;
381                     case XK_n:
382                         if ( KEYSTATEMASK( msg.key.keystate ) == 0 ) {
383                             nextMatch();
384                         }
385                         break;
386                     case XK_p:
387                         if ( KEYSTATEMASK( msg.key.keystate ) == 0 ) {
388                             nextMatch( true );
389                         }
390                         break;
391                     case XK_Return:
392                         nextMatch();
393                         break;
394                 }
395                 wcb->setState( tv->getLineWrap() );
396                 slncb->setState( tv->getShowLineNumbers() );
397             }
398             break;
399         case AG_STRINGGADGET_OK:
400             if ( msg.stringgadget.sg == search_sg ) {
401                 search_sg->activate();
402             }
403         case AG_STRINGGADGET_CONTENTCHANGE:
404             if ( msg.stringgadget.sg == search_sg ) {
405                 nextMatch();
406             }
407             break;
408         case AG_TEXTVIEW_END_REACHED:
409             if ( msg.textview.textview == tv &&
410                  ts->incompleteFile() ) {
411                 ts->readMore();
412                 tv->textStorageChanged();
413                 if ( ts->incompleteFile() == false ) {
414                     readmoreb->hide();
415                 }
416             }
417             break;
418     }
419 
420     if ( endmode == 0 ) {
421         aguix->unregisterBGHandler( win );
422         FileViewer::setGlobalLineWrap( tv->getLineWrap() );
423         FileViewer::setGlobalShowLineNumbers( tv->getShowLineNumbers() );
424     }
425 }
426 
getAWindow()427 AWindow *FileViewerBG::getAWindow()
428 {
429     return win;
430 }
431 
buildTextView(const std::string & filename,AContainer * ac1,class Text * fnt,const RefCount<AWidth> & lencalc)432 int FileViewerBG::buildTextView( const std::string &filename,
433                                  AContainer *ac1,
434                                  class Text *fnt,
435                                  const RefCount<AWidth> &lencalc )
436 {
437     AGUIX *aguix = Worker::getAGUIX();
438     const int cmin = AContainer::ACONT_MINH +
439         AContainer::ACONT_MINW;
440 
441     if ( ac1 == NULL ) return 1;
442 
443     NWC::FSEntry fse( filename );
444     loff_t file_length = 0;
445     int initial_size = ( m_wrap_mode == true ) ? ( 512 * 1024 ) : ( 2 * 1024 * 1024 );
446     bool continue_viewing = true;
447 
448     file_length = PDatei::getFileSize( filename );
449 
450     if ( file_length > initial_size ) {
451         std::string l1, l2;
452         int cancel_button;
453 
454         l1 = AGUIXUtils::bytes_to_human_readable_f( file_length );
455         l2 = AGUIXUtils::bytes_to_human_readable_f( (double)initial_size );
456 
457         char *textstr = (char*)_allocsafe( strlen( catalog.getLocale( 764 ) ) +
458                                            l1.length() + l2.length() + 1 );
459         sprintf( textstr, catalog.getLocale( 764 ), l1.c_str(), l2.c_str() );
460 
461         std::string buttontext = catalog.getLocale( 765 );
462         buttontext += "|";
463         buttontext += catalog.getLocale( 766 );
464 
465         if ( m_wrap_mode == true ) {
466             buttontext += "|";
467             buttontext += catalog.getLocale( 767 );
468 
469             cancel_button = 3;
470         } else {
471             cancel_button = 2;
472         }
473 
474         buttontext += "|";
475         buttontext += catalog.getLocale( 8 );
476 
477         int erg = Worker::getRequester()->request( catalog.getLocale( 123 ),
478                                                    textstr,
479                                                    buttontext.c_str(),
480                                                    win,
481                                                    Requester::REQUEST_NONE );
482         if ( erg == 1 ) {
483             if ( file_length > 1 * 1024 * 1024 * 1024 ) {
484                 initial_size = 1 * 1024 * 1024 * 1024;
485             } else {
486                 initial_size = file_length;
487             }
488         } else if ( erg == cancel_button ) {
489             continue_viewing = false;
490         } else if ( erg == 2 ) {
491             if ( file_length > 1 * 1024 * 1024 * 1024 ) {
492                 initial_size = 1 * 1024 * 1024 * 1024;
493             } else {
494                 initial_size = file_length;
495             }
496             m_wrap_mode = false;
497         }
498         _freesafe( textstr );
499     }
500 
501     if ( continue_viewing == false ) {
502         return 2;
503     }
504 
505     if ( tv != NULL ) {
506         delete tv;
507     }
508     if ( ts != NULL ) {
509         delete ts;
510     }
511     ts = new TextStorageFile( filename, lencalc, initial_size, TextStorageString::CONVERT_NON_PRINTABLE_SIMPLE );
512     tv = new TextView( aguix, 0, 0, 100, 100, "", *ts );
513 
514     ts_search = new SearchTextStorage( *ts );
515 
516     tv->setDisplayFocus( true );
517     tv->setFont( wconfig->getFont( 4 ).c_str() );
518     ac1->add( tv, 0, 1, cmin );
519     tv->create();
520     if ( fnt != NULL ) fnt->setText( filename.c_str() );
521     ac1->rearrange();
522     tv->show();
523 
524     std::string title = AGUIXUtils::formatStringToString( catalog.getLocale( 1079 ), filename.c_str() );
525 
526     win->setTitle( title.c_str() );
527 
528     return 0;
529 }
530 
jumpToLine()531 void FileViewerBG::jumpToLine()
532 {
533     int erg;
534     std::string buttons;
535     char *return_str = NULL;
536 
537     buttons = catalog.getLocale( 716 );
538     buttons += "|";
539     buttons += catalog.getLocale( 8 );
540 
541     //TODO use current line number as default but I need the interface in tv for this first
542     erg = win->string_request( catalog.getLocale( 123 ),
543                                catalog.getLocale( 717 ),
544                                "",
545                                buttons.c_str(),
546                                &return_str );
547     if ( erg == 0 && return_str != NULL ) {
548         int line_nr = 0;
549         line_nr = atoi( return_str ) - 1;
550         tv->jumpToLine( line_nr, true );
551     }
552     if ( return_str != NULL )
553         _freesafe( return_str );
554 }
555 
nextMatch(bool backwards)556 void FileViewerBG::nextMatch( bool backwards )
557 {
558     if ( backwards ) {
559         ts_search->searchBackwards( search_sg->getText() );
560     } else {
561         ts_search->search( search_sg->getText() );
562     }
563     ts_search->highlightCurMatch( *tv );
564     tv->makeSelectionVisible();
565 
566     if ( strlen( search_sg->getText() ) < 1 ) {
567         m_find_pos_text->setText( "" );
568     } else {
569         int match_line = ts_search->getCurMatchLine();
570 
571         if ( match_line < 0 ) {
572             m_find_pos_text->setText( catalog.getLocale( 1140 ) );
573         } else {
574             std::string info = AGUIXUtils::formatStringToString( catalog.getLocale( 1141 ), match_line + 1 );
575 
576             m_find_pos_text->setText( info.c_str() );
577         }
578     }
579 }
580 
setLineWrap(bool nv)581 void FileViewerBG::setLineWrap( bool nv )
582 {
583     m_wrap_mode = nv;
584 }
585 
getLineWrap() const586 bool FileViewerBG::getLineWrap() const
587 {
588     return m_wrap_mode;
589 }
590 
setShowLineNumbers(bool nv)591 void FileViewerBG::setShowLineNumbers( bool nv )
592 {
593     m_showlinenumbers_mode = nv;
594 }
595 
getShowLineNumbers() const596 bool FileViewerBG::getShowLineNumbers() const
597 {
598     return m_showlinenumbers_mode;
599 }
600 
restartSearchFromTop()601 void FileViewerBG::restartSearchFromTop()
602 {
603     ts_search->setSearchStartLine( 0 );
604     nextMatch();
605 }
606 
showInWorkerTab()607 void FileViewerBG::showInWorkerTab()
608 {
609     if ( ! m_worker ) return;
610 
611     auto it1 = m_filelist.begin();
612 
613     if ( it1 == m_filelist.end() ) return;
614 
615     Lister *l1;
616 
617     l1 = m_worker->getActiveLister();
618     if ( l1 != NULL ) {
619         l1->switch2Mode( 0 );
620 
621         VirtualDirMode *vdm = dynamic_cast< VirtualDirMode* >( l1->getActiveMode() );
622         if ( vdm != NULL ) {
623             vdm->newTab();
624 
625             vdm->showDir( *it1 );
626         }
627     }
628 }
629