flu_file_chooser.cpp

来自「ncbi源码」· C++ 代码 · 共 2,471 行 · 第 1/5 页

CPP
2,471
字号
}Flu_File_Chooser :: FileColumns :: FileColumns( int x, int y, int w, int h, Flu_File_Chooser *c )  : Fl_Tile( x, y, w, h ){  chooser = c;  W1 = int(float(w)*0.35f);  W2 = int(float(w)*0.20f);  W3 = int(float(w)*0.15f);  W4 = w-W1-W2-W3;  Fl_Box *box = new Fl_Box( x+50, y, w-200, h );  add_resizable( *box );  c->detailNameBtn = new Flu_Button( x, y, W1, h, "Name" );  c->detailNameBtn->align( FL_ALIGN_CLIP );  c->detailNameBtn->callback( Flu_File_Chooser::_sortCB, c );  {    CBTile *tile = new CBTile( x+W1, y, W2+W3+W4, h, c );    Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-150, tile->h() );    tile->add_resizable( *box );    c->detailTypeBtn = new Flu_Button( x+W1, y, W2, h, "Type" );    c->detailTypeBtn->align( FL_ALIGN_CLIP );    c->detailTypeBtn->callback( Flu_File_Chooser::_sortCB, c );    {      CBTile *tile = new CBTile( x+W1+W2, y, W3+W4, h, c );      Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-100, tile->h() );      tile->add_resizable( *box );      c->detailSizeBtn = new Flu_Button( x+W1+W2, y, W3, h, "Size" );      c->detailSizeBtn->align( FL_ALIGN_CLIP );      c->detailSizeBtn->callback( Flu_File_Chooser::_sortCB, c );      c->detailDateBtn = new Flu_Button( x+W1+W2+W3, y, W4, h, "Date" );      c->detailDateBtn->align( FL_ALIGN_CLIP );      c->detailDateBtn->callback( Flu_File_Chooser::_sortCB, c );      tile->end();    }    tile->end();  }  end();}Flu_File_Chooser :: FileColumns :: ~FileColumns(){}void Flu_File_Chooser :: FileColumns :: resize( int x, int y, int w, int h ){  // TODO resize the buttons/tiles according to their stored relative sizes  Fl_Tile::resize( x, y, w, h );}int Flu_File_Chooser :: FileColumns :: handle( int event ){  if( event == FL_DRAG )    {      // the user is probably dragging to resize the columns      // update the sizes for each entry      chooser->updateEntrySizes();      chooser->redraw();    }  return Fl_Tile::handle(event);}void Flu_File_Chooser :: filenameCB(){  filenameEnterCallback = true;  cd( filename.value() );}inline bool _isProbablyAPattern( const char *s ){  return( strpbrk( s, "*;|[]?" ) != NULL );}void Flu_File_Chooser :: okCB(){  // only hide if the filename is not blank or the user is choosing directories,  // in which case use the current directory  //printf( "%s\n", filename.value() );  if( selectionType & DIRECTORY )    {#ifdef WIN32      if( strcmp( filename.value(), "My Computer" ) == 0 )	return;#endif      if( !(selectionType & MULTI ))	{	  if( strlen( filename.value() ) != 0 )	    cd( filename.value() );	  filename.value( currentDir.c_str() );	  filename.position( filename.size(), filename.size() );	}      hide();    }  else    {      if( strlen( filename.value() ) != 0 )	{	  if( _isProbablyAPattern( filename.value() ) )	    {	      cd( filename.value() );	      return;	    }#ifdef WIN32	  if( filename.value()[1] == ':' )#else	  if( filename.value()[0] == '/' )#endif	    if( fl_filename_isdir( filename.value() ) )	      {		filename.value( "" );		return;	      }	  // prepend the path	  FluSimpleString path = currentDir + filename.value();	  filename.value( path.c_str() );	  filename.position( filename.size(), filename.size() );	  hide();	}    }}void Flu_File_Chooser :: homeCB(){#ifdef WIN32  cd( "/" );#else  cd( userHome.c_str() );#endif}void Flu_File_Chooser :: desktopCB(){#ifdef WIN32  FluSimpleString s = "/Desktop";#else  FluSimpleString s = userHome + "Desktop";#endif  cd( s.c_str() );}#define QSCANL( field ) \      while( ((Flu_File_Chooser::Entry*)array[left])->field < \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++#define QSCANR( field ) \      while( ((Flu_File_Chooser::Entry*)array[right])->field > \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) right--#define RQSCANL( field ) \      while( ((Flu_File_Chooser::Entry*)array[left])->field > \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++#define RQSCANR( field ) \      while( ((Flu_File_Chooser::Entry*)array[right])->field < \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) right--#define CASE_QSCANL( field ) \      while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++#define CASE_QSCANR( field ) \      while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right--#define CASE_RQSCANL( field ) \      while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++#define CASE_RQSCANR( field ) \      while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right--#define CUSTOM_QSCANL( field ) \      while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++#define CUSTOM_QSCANR( field ) \      while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right--#define CUSTOM_RQSCANL( field ) \      while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \             ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++#define CUSTOM_RQSCANR( field ) \      while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \	     ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right--void Flu_File_Chooser :: _qSort( int how, bool caseSort, Fl_Widget **array, int low, int high ){  int left, right, pivot;  Fl_Widget *temp;  bool reverse = ( how & SORT_REVERSE );  if( high > low )    {      left = low;      right = high;      pivot = low;      while( right >= left )	{	  switch( how & ~SORT_REVERSE )	    {	    case SORT_NAME:	      if( reverse )		{		  if( customSort )		    {		      CUSTOM_RQSCANL( filename.c_str() );		      CUSTOM_RQSCANR( filename.c_str() );		    }		  else if( !caseSort )		    {		      CASE_RQSCANL( filename );		      CASE_RQSCANR( filename );		    }		  else		    {		      RQSCANL( filename );		      RQSCANR( filename );		    }		}	      else		{		  if( customSort )		    {		      CUSTOM_QSCANL( filename.c_str() );		      CUSTOM_QSCANR( filename.c_str() );		    }		  else if( !caseSort )		    {		      CASE_QSCANL( filename );		      CASE_QSCANR( filename );		    }		  else		    {		      QSCANL( filename );		      QSCANR( filename );		    }		}	      break;	    case SORT_SIZE:	      if( reverse )		{		  RQSCANL( isize );		  RQSCANR( isize );		}	      else		{		  QSCANL( isize );		  QSCANR( isize );		}	      break;	    case SORT_DATE:	      if( reverse )		{		  RQSCANL( idate );		  RQSCANR( idate );		}	      else		{		  QSCANL( idate );		  QSCANR( idate );		}	      break;	    case SORT_TYPE:	      if( reverse )		{		  RQSCANL( description );		  RQSCANR( description );		}	      else		{		  QSCANL( description );		  QSCANR( description );		}	      break;	    }	  if( left > right )	    break;	  temp = array[left];	  array[left] = array[right];	  array[right] = temp;	  left++;	  right--;	}      _qSort( how, caseSort, array, low, right );      _qSort( how, caseSort, array, left, high );    }}Flu_File_Chooser :: FileList :: FileList( int x, int y, int w, int h, Flu_File_Chooser *c )  : Flu_Wrap_Group( x, y, w, h ){  chooser = c;}Flu_File_Chooser :: FileList :: ~FileList(){}void Flu_File_Chooser :: FileList :: sort( int n ){  if( n != -1 )    numDirs = n;  if( children() == 0 )    return;  // the directories are already first. sort the directories then the names lexigraphically  //if( chooser->sortMethod & Flu_File_Chooser::SORT_NAME )  Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 );  Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 );  chooser->redraw();}int Flu_File_Chooser :: FileList :: handle( int event ){  //printf( "%d\n", event );  if( event == FL_FOCUS || event == FL_UNFOCUS )    return 1;  if( Flu_Wrap_Group::handle( event ) )    return 1;  // if push on no file, unselect all files and turn off editing mode  if( event == FL_PUSH && !Fl::event_key( FL_SHIFT ) && !Fl::event_key( FL_CTRL ) )    {      chooser->unselect_all();      chooser->filename.value( "" );      chooser->filename.position( chooser->filename.size(), chooser->filename.size() );      if( Fl::event_button3() )	return chooser->popupContextMenu( NULL );      return 1;    }  else if( event == FL_KEYDOWN )    {      if( Fl::event_key( FL_Delete ) )	{	  // recycle by default, unless the shift key is held down	  chooser->trashCB( !Fl::event_state( FL_SHIFT ) );	  return 1;	}      Flu_File_Chooser::Entry *e = chooser->lastSelected;      if( !e )	{	  for( int i = 0; i < children(); i++ )	    if( ((Flu_File_Chooser::Entry*)child(i))->selected )	      {		e = (Flu_File_Chooser::Entry*)child(i);		break;	      }	}      if( e )	{	  switch( Fl::event_key() )	    {	    case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e );	      if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break;	    case FL_Down: e = (Flu_File_Chooser::Entry*)next( e );	      if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break;	    case FL_Left: e = (Flu_File_Chooser::Entry*)left( e ); break;	    case FL_Right: e = (Flu_File_Chooser::Entry*)right( e ); break;	    case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break;	    case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break;	    case FL_Enter:	      chooser->filenameEnterCallback = true;	      chooser->cd( e->filename.c_str() );	      return 1;	    case ' ':	      chooser->cd( e->filename.c_str() );	      return 1;	    default: e = 0; break;	    }	  if( e )	    {	      chooser->unselect_all();	      e->selected = true;	      chooser->lastSelected = e;	      chooser->filename.value( e->filename.c_str() );	      chooser->filename.position( chooser->filename.size(), chooser->filename.size() );	      chooser->redraw();	      scroll_to( e );	      //take_focus();	      return 1;	    }	}    }  return 0;}Flu_File_Chooser :: FileDetails :: FileDetails( int x, int y, int w, int h, Flu_File_Chooser *c )  : Fl_Pack( x, y, w, h ){  chooser = c;}Flu_File_Chooser :: FileDetails :: ~FileDetails(){}void Flu_File_Chooser :: FileDetails :: scroll_to( Fl_Widget *w ){  // we know all the widgets are the same height  // so just find this widget and scroll to the accumulated height  int H = 0;  for( int i = 0; i < children(); i++ )    {      if( child(i) == w )	{	  if( H > (int)chooser->filescroll->scrollbar.maximum() )	    H = (int)chooser->filescroll->scrollbar.maximum();	  chooser->filescroll->position( 0, H );	  return;	}      H += w->h();    }}void Flu_File_Chooser :: FileDetails :: sort( int n ){  if( n != -1 )    numDirs = n;  if( children() == 0 )    return;  // the directories are already first. sort the directories then the names lexigraphically  //if( chooser->sortMethod & Flu_File_Chooser::SORT_NAME )  Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 );  Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 );  chooser->redraw();}Fl_Widget* Flu_File_Chooser :: FileDetails :: next( Fl_Widget* w ){  for( int i = 0; i < children()-1; i++ )    {      if( w == child(i) )	return child(i+1);    }  return NULL;}Fl_Widget* Flu_File_Chooser :: FileDetails :: previous( Fl_Widget* w ){  for( int i = 1; i < children(); i++ )    {      if( w == child(i) )	return child(i-1);    }  return NULL;}int Flu_File_Chooser :: FileDetails :: handle( int event ){  if( event == FL_FOCUS || event == FL_UNFOCUS )    return 1;  if( Fl_Pack::handle( event ) )    return 1;  else if( event == FL_PUSH )    return 1;  else if( event == FL_KEYDOWN )    {      if( Fl::event_key( FL_Delete ) )	{	  // recycle by default, unless the shift key is held down	  chooser->trashCB( !Fl::event_state( FL_SHIFT ) );	  return 1;	}      Flu_File_Chooser::Entry *e = chooser->lastSelected;      if( !e )	{	  for( int i = 0; i < children(); i++ )	    if( ((Flu_File_Chooser::Entry*)child(i))->selected )	      {		e = (Flu_File_Chooser::Entry*)child(i);		break;	      }	}      if( e )	{	  switch( Fl::event_key() )	    {	    case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e );	      if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break;	    case FL_Down: e = (Flu_File_Chooser::Entry*)next( e );	      if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break;	    case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break;	    case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break;	    case FL_Enter:	      chooser->filenameEnterCallback = true;	      chooser->cd( e->filename.c_str() );	      return 1;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?