flu_file_chooser.cpp

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

CPP
2,471
字号
	    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 :: Entry :: Entry( const char* name, int t, bool d, Flu_File_Chooser *c )  : Fl_Input( 0, 0, 0, 0 ){  resize( 0, 0, DEFAULT_ENTRY_WIDTH, 20 );  labelsize( 12 );  textsize( 12 );  box( FL_BORDER_BOX );  when( FL_WHEN_RELEASE_ALWAYS | FL_WHEN_ENTER_KEY_ALWAYS );  callback( _inputCB, this );  filename = name;  selected = false;  chooser = c;  details = d;  type = t;  icon = NULL;  editMode = 0;  description = "";  updateSize();  updateIcon();}void Flu_File_Chooser :: Entry :: updateIcon(){  Flu_File_Chooser::FileTypeInfo *tt = NULL;  if( type==ENTRY_MYCOMPUTER )    {      icon = &computer;      description = "My Computer";    }  else if( type==ENTRY_MYDOCUMENTS )    {      icon = &documents;      description = "My Documents";    }  else if( type==ENTRY_DRIVE )    {      //icon = &disk_drive;      //description = "";    }  else if( type==ENTRY_DIR || type==ENTRY_FAVORITE )    tt = Flu_File_Chooser::find_type( NULL );  else    {      const char *dot = strrchr( filename.c_str(), '.' );      if( dot )	{	  tt = Flu_File_Chooser::find_type( dot+1 );	  if( !tt )	    description = dot+1;	}    }  if( tt )    {      icon = tt->icon;      description = tt->type;    }  // if there is no icon, assign a default one  if( !icon && type==ENTRY_FILE )    icon = chooser->defaultFileIcon;  if( type==ENTRY_FAVORITE )    icon = &little_favorites;  toolTip = "Name: " + filename;  if( type == ENTRY_FILE )    toolTip += "\nSize: " + filesize;  toolTip += "\nType: " + description;  tooltip( toolTip.c_str() );  redraw();}void Flu_File_Chooser :: resize( int x, int y, int w, int h ){  Fl_Double_Window::resize( x, y, w, h );  if( fileListWideBtn->value() )    filelist->scrollbar.linesize( filelist->w() );  else if( fileListBtn->value() )    filelist->scrollbar.linesize( DEFAULT_ENTRY_WIDTH+4 );  for( int i = 0; i < filelist->children(); i++ )    ((Entry*)filelist->child(i))->updateSize();}void Flu_File_Chooser :: Entry :: updateSize(){  if( type==ENTRY_FAVORITE || chooser->fileListWideBtn->value() )    {      resize( x(), y(), chooser->filelist->w()-4, 20 );    }  if( details )    {      nameW = chooser->detailNameBtn->w();      typeW = chooser->detailTypeBtn->w();      sizeW = chooser->detailSizeBtn->w();      dateW = chooser->detailDateBtn->w();      resize( x(), y(), chooser->filedetails->w(), 20 );    }  else    nameW = w();  // how big is the icon?  int iW = 0, iH = 0;  if( icon )    {      iW = icon->w()+2;      iH = icon->h();    }  fl_font( labelfont(), labelsize() );  // measure the name and see if we need a truncated version  int W = 0, H = 0;  fl_measure( filename.c_str(), W, H );    if( W > nameW-iW )    {      // progressively strip characters off the end of the name until      // it fits with "..." at the end      if( altname[0] != '\0' )	shortname = altname;      else	shortname = filename;      int len = shortname.size();      while( W > (nameW-iW) && len > 3 )	{	  shortname[len-3] = '.';	  shortname[len-2] = '.';	  shortname[len-1] = '.';	  shortname[len] = '\0';	  len--;	  W = 0;	  fl_measure( shortname.c_str(), W, H );  	}    }  else    shortname = "";  // measure the description and see if we need a truncated version  shortDescription = "";  if( details )    {      W = 0; H = 0;      fl_measure( description.c_str(), W, H );        if( W > typeW-4 )	{	  // progressively strip characters off the end of the description until	  // it fits with "..." at the end	  shortDescription = description;	  int len = shortDescription.size();	  while( W > typeW-4 && len > 3 )	    {	      shortDescription[len-3] = '.';	      shortDescription[len-2] = '.';	      shortDescription[len-1] = '.';	      shortDescription[len] = '\0';	      len--;	      W = 0;	      fl_measure( shortDescription.c_str(), W, H );  	    }	}    }  redraw();}Flu_File_Chooser :: Entry :: ~Entry(){}void Flu_File_Chooser :: Entry :: inputCB(){  redraw();  // if the user tried to change the string to nothing, restore the original name and turn off edit mode  if( strlen( value() ) == 0 )    {      editMode = 0;      return;    }  // if input text is different from filename, try to change the filename  if( strcmp( value(), filename.c_str() ) != 0 )    {      // build the total old filename and new filename      FluSimpleString oldName = chooser->currentDir + filename,	newName = chooser->currentDir + value();      // see if new name already exists      struct stat s;      int result = ::stat( newName.c_str(), &s );      if( result == 0 )	{	  fl_alert( "File '%s' already exists!", newName.c_str() );	  return;  // leave editing on	}      if( rename( oldName.c_str(), newName.c_str() ) == -1 )	{	  fl_alert( "Unable to rename '%s' to '%s'", oldName.c_str(), newName.c_str() );	  //return;  // leave editing on	}      else	{	  filename = value();	  updateSize();	  updateIcon();	}      // QUESTION: should we set the chooser filename to the modified name?      //chooser->filename.value( filename.c_str() );    }  // only turn off editing if we have a successful name change  editMode = 0;}Fl_Group* Flu_File_Chooser :: getEntryGroup(){  return (!fileDetailsBtn->value() || currentDir == FAVORITES_UNIQUE_STRING ) ? &(filelist->group) : filedetails;}Fl_Group* Flu_File_Chooser :: getEntryContainer(){  return (!fileDetailsBtn->value() || currentDir == FAVORITES_UNIQUE_STRING ) ? (Fl_Group*)filelist : filedetails;}int Flu_File_Chooser :: Entry :: handle( int event ){  if( editMode )    {      // if user hits 'Escape' while in edit mode, restore the original name and turn off edit mode      if( event == FL_KEYDOWN && Fl::event_key( FL_Escape ) )	{	  editMode = 0;	  redraw();	  if( selected )	    chooser->trashBtn->activate();	  return 1;	}      return Fl_Input::handle( event );    }  if( event == FL_FOCUS || event == FL_UNFOCUS )    return 1;  if( event == FL_ENTER || event == FL_LEAVE )    return 1;  Fl_Group *g = chooser->getEntryGroup();  if( event == FL_PUSH )    {      if( Fl::event_clicks() > 0 )	{	  Fl::event_clicks(0);	  // double-clicking a favorite cd's to it	  if( type == ENTRY_FAVORITE )	    {	      chooser->delayedCd = filename;	      Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, chooser );	    }	  // double-clicking a directory cd's to it	  else if( type != ENTRY_FILE )	    {#ifdef WIN32	      if( filename[1] == ':' )		chooser->delayedCd = filename;	      else#endif		chooser->delayedCd = chooser->currentDir + filename + "/";	      Fl::add_timeout( 0.0f, Flu_File_Chooser::delayedCdCB, chooser );	    }	  // double-clicking a file chooses it if we are in file selection mode	  else if( (chooser->selectionType & DIRECTORY) == 0 )	    {	      // prepend the path	      FluSimpleString path = chooser->currentDir + filename;	      chooser->filename.value( path.c_str() );	      //chooser->filename.value( filename.c_str() );	      chooser->filename.position( chooser->filename.size(), chooser->filename.size() );	      Fl::add_timeout( 0.0f, Flu_File_Chooser::selectCB, chooser );	    }	  if( selected )	    chooser->trashBtn->activate();	  return 1;	}      /*      if( selected && !Fl::event_button3() && !Fl::event_state(FL_CTRL) && !Fl::event_state(FL_SHIFT) )	{	  // only allow editing of certain files and directories	  if( chooser->fileEditing && ( type == ENTRY_FILE || type == ENTRY_DIR ) )	    {	      // if already selected, switch to input mode	      Fl::add_timeout( 1.0, _editCB, this );	      return 1;	    }	}	else*/ if( chooser->selectionType & MULTI )	{	  if( Fl::event_state(FL_CTRL) )	    {	      selected = !selected;  // toggle this item	      chooser->lastSelected = this;	      if( type == ENTRY_FILE )		chooser->previewGroup->file = chooser->currentDir + filename;	      chooser->redraw();	      chooser->getEntryContainer()->take_focus();	    }	  else if( Fl::event_state(FL_SHIFT) )	    {	      // toggle all items from the last selected item to this one	      if( chooser->lastSelected == NULL )		{		  selected = true;		  chooser->lastSelected = this;		  if( type == ENTRY_FILE )		    chooser->previewGroup->file = chooser->currentDir + filename;		  chooser->redraw();		  chooser->getEntryContainer()->take_focus();		}	      else		{		  // get the index of the last selected item and this item		  int lastindex = -1, thisindex = -1;		  int i;		  for( i = 0; i < g->children(); i++ )		    {		      if( g->child(i) == chooser->lastSelected )			lastindex = i;		      if( g->child(i) == this )			thisindex = i;		      if( lastindex >= 0 && thisindex >= 0 )			break;		    }		  if( lastindex >= 0 && thisindex >= 0 )		    {		      // loop from this item to the last item, toggling each item except the last		      int inc;		      if( thisindex > lastindex )			inc = -1;		      else			inc = 1;		      Entry *e;		      for( i = thisindex; i != lastindex; i += inc )			{			  e = (Entry*)g->child(i);			  e->selected = !e->selected;			  e->redraw();			}		      chooser->lastSelected = this;		      if( type == ENTRY_FILE )			chooser->previewGroup->file = chooser->currentDir + filename;		      chooser->redraw();		      chooser->getEntryContainer()->take_focus();		    }		}	    }	  else	    {	      chooser->unselect_all();	      selected = true;	      chooser->lastSelected = this;	      if( type == ENTRY_FILE )		chooser->previewGroup->file = chooser->currentDir + filename;	      chooser->redraw();	      chooser->getEntryContainer()->take_focus();	    }	}      else	{	  chooser->unselect_all();	  selected = true;	  chooser->lastSelected = this;	  if( type == ENTRY_FILE )	    chooser->previewGroup->file = chooser->currentDir + filename;	  chooser->redraw();	  chooser->getEntryContainer()->take_focus();	}      //g->take_focus();      redraw();      if( selected )	chooser->trashBtn->activate();      if( Fl::event_button3() )	return chooser->popupContextMenu( this );      // don't put the filename into the box if we are directory but we are not choosing directories      if( (chooser->selectionType & Flu_File_Chooser::DIRECTORY)  ||  type==ENTRY_FILE )	chooser->filename.value( filename.c_str() );      else	chooser->filename.value( "" );      chooser->filename.position( chooser->filename.size(), chooser->filename.size() );      return 1;    }  else if( event == FL_DRAG )    {      if( chooser->selectionType & MULTI )	{	  // toggle all items from the last selected item to this one	  if( chooser->lastSelected != NULL )	    {	      selected = true;	      // get the index of the last selected item and this item	      int lastindex = -1, thisindex = -1;	      int i;	      for( i = 0; i < g->children(); i++ )		{		  if( g->child(i) == chooser->lastSelected )		    lastindex = i;		  if( g->child(i) == this )		    thisindex = i;		  if( lastindex >= 0 && thisindex >= 0 )		    break;		}	      if( lastindex >= 0 && thisindex >= 0 )		{		  // loop from this item to the last item, toggling each item except the last		  int inc;		  if( thisindex > lastindex )		    inc = -1;		  else		    inc = 1;		  Entry *e;		  for( i = thisindex; i != lastindex; i += inc )		    {		      e = (Entry*)g->child(i);		      e->selected = !e->selected;		      e->redraw();		    }		  chooser->lastSelected = this;		  if( type == ENTRY_FILE )		    chooser->previewGroup->file = chooser->currentDir + filename;		  chooser->redraw();		}	      redraw();	      chooser->getEntryContainer()->take_focus();	      if( selected )		chooser->trashBtn->activate();	      return 1;	    }	}    }  return Fl_Widget::handle(event);}void Flu_File_Chooser :: Entry :: editCB(){  // if already selected, switch to input mode  editMode = 2;  value( filename.c_str() );  take_focus();  // select the text up to but not including the extension  const char *dot = strrchr( filename.c_str(), '.' );  if( dot )    position( 0, dot-filename.c_str() );  else    position( 0, filename.size() );  chooser->trashBtn->deactivate();  redraw();}int Flu_File_Chooser :: popupContextMenu( Entry *entry ){  int type = entry ? entry->type : ENTRY_NONE;  const char *filename = entry ? entry->filename.c_str() : NULL;  char *ext = 

⌨️ 快捷键说明

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