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 + -
显示快捷键?