gogglesmm-0.12.7/0000755000175000001440000000000012063217121012300 5ustar sxjusersgogglesmm-0.12.7/README0000644000175000001440000001107611670036275013201 0ustar sxjusersSupport ------- Found a bug, want a feature or tell how great Goggles Music Manager is/sucks. Please mail me at s.jansen@gmail.com or file an issue at http://code.google.com/p/gogglesmm Installation ------------ Read the INSTALL file on how to build and install Goggles Music Manager on your machine. Name Unification ---------------- Before 0.10.23 Goggles Music Manager used various abbreviations to refer to itself (musicmanager,gmm,gogglesm). To avoid confusion, this naming has been unified in 0.10.23. Since a lot of distributions already used gogglesmm, it was decided to use 'gogglesmm' as the standard base name. The following things are affected by this change: - The source package has been renamed to 'gogglesmm-x.y.z.tar.*' - The executable has been renamed from 'gmm' to 'gogglesmm' - The extra desktop files (gmm.desktop and gmm.png) have been renamed to (gogglesmm.desktop and gogglesmm.png) If you provide binary packages for Goggles Music Manager please distribute with the gogglesmm name. Upgrading --------- If you are using Goggles Music Manager 0.7.x, please note that you will have to reimport your music due to changes in the database. The database for 0.8.x / 0.9.x / 0.10.x / 0.11.x users are automatically upgraded. FOX 1.6 / FOX 1.7 ------------------ Any FOX-1.6.x should work. I recommend to get latest version available (1.6.44 at the time of writing). Use FOX-1.7.x at your own risk. In general it should work with the latest release and development snapshot. If it doesn't, you could try to fix it yourself or wait for me to catch up with the latest FOX changes. Last.fm ------- Join the Goggles Music Manager group: http://www.last.fm/group/Goggles+Music+Manager To start scrobble tracks: Go to and fill in your lastfm username and password. If Goggles Music Manager can successfully authenticate with the lastfm service tracks, will automatically get 'scrobbled'. If no internet connection is present (or a invalid user/password has been given), tracks to be submitted will be queued until a internet connection can be established again. The queue is kept in ~/.goggles/scrobbler.cache. To stop scrobble tracks: Uncheck last.fm or remove the lastfm username and password from preferences dialog. Note that tracks won't be queued either. Limitations / Implementation Details * Uses audioscrobbler realtime submission protocol v1.2 * No proxy support. * Standard 1 minute delay before submitting played tracks. * 80% of track need to be played to be counted as played. Only tracks longer than 30sec will be submitted to last-fm. Audio Configuration ------------------- Specific configuration settings for XINE may be set in ~/.goggles/xineconf Run and play a track in Goggles Music Manager once to automatically create a default configuration. Keyboard Shortcuts ------------------ Ctrl-N Reset default sorting order in current view. Ctrl-R Shuffle track list. Ctrl-B Toggles browse mode on or off. Ctrl-G Toggles Genre list in browse mode. Ctrl-O Import files from given directory. Ctrl-J Jump to playing song in track list. Ctrl-F Find / Find Ctrl-S Show source browser Ctrl-P Start / Pause playback. Ctrl-\ Stop playback. Ctrl-[ Play previous track. Ctrl-] Play next track. Ctrl-T Toggle Repeat A-B. Ctrl-A Select All in lists. Ctrl-Q Quit Goggles Music Manager. Ctrl-W Close Window Ctrl-M / F11 Toggle between Mini Player and full browser. F12 Toggle Full Screen. F2 Edit selected track, album, artist or genre. Del Delete selected track, album, artist or genre. Sorting ------- The following sort options are available for the track list: Browse: [only available in browse mode] Sort on album, sort on artist and sort on track number. Note that artist and album can be either ascending or descending based on the sorting order of the album and artist list. Shuffle: Try to randomize the order of the tracks. By Genre: Sort on genre, sort on artist, sort on album and sort on track number. By Artist: Sort on artist, sort on album, sort on track number By Album: Sort on album, sort on track number By Time: Sort on time By Track Number: Sort on track number By Title: Sort on title For artists and albums special keywords may be set in the preferences panel to exclude certain common words from sorting on. gogglesmm-0.12.7/extra/0000755000175000001440000000000011573755075013447 5ustar sxjusersgogglesmm-0.12.7/extra/gogglesmm.desktop0000644000175000001440000000150611643051173017007 0ustar sxjusers[Desktop Entry] Name=Goggles Music Manager Name[en_CA]=Goggles Music Manager Name[en_GB]=Goggles Music Manager Name[nl]=Goggles muziekspeler Name[pt]= Goggles - Reprodutor de músicas GenericName=Music Player GenericName[en_CA]=Music Player GenericName[en_GB]=Music Player GenericName[nl]=Muziekspeler GenericName[pt]=Reprodutor de músicas Comment=Play and organize your music collection Comment[en_CA]=Play and organize your music collection Comment[en_GB]=Play and organise your music collection Comment[nl]=Luister and beheer uw muziekcollectie Comment[pt]=Reprodução e organização de músicas Exec=gogglesmm %u Terminal=false Hidden=false Type=Application Icon=gogglesmm Categories=Application;AudioVideo;Audio;Player; MimeType=audio/flac;audio/ogg;audio/x-vorbis;audio/x-vorbis+ogg;audio/mpeg;audio/mp4a-latm;audio/x-musepack; gogglesmm-0.12.7/extra/gogglesmm_24.png0000644000175000001440000000270212063217122016421 0ustar sxjusersPNG  IHDRw=bKGDwIDATHUYlTUrܙ;3L BŖbkEKD KD4D.1Q#j|cF⃈&`]#Y4(*҈"bNYP,C[Q|s~@A͗cAWZBrQ Om|:φ`pE?a~-qbl˅BMtzռQV^°g'7`Y9r"86zw{tbtCNoT;n_{+0|Vi-Nyr1@GнMn.&e]qo% J |=˚ʯʄ3}/qm})wt~U;uP{I- :"a=E}ggՕ<Ը@e5슕˼Nr.p;oS_)Il-aJu LS@K \蘔nXu] 䁝m3 lJ4E#,dqDaۓ1)y€0ń,],.@ -(% *94}r9Olq!{PB(g'89 ?gRH*_Zx \uXzaCbÿKwS';y uÜ[xCm]SCK:s{kE|島}P3v"u*jb}DߑUՇ"7T|!'X34{908L-}][dl3T<ʲܜ[PC)+TJ"0xٺk9O!i6:bqvwΘB΅V|6E#=;@(P)A&|._0ܾ/Td$tj0s!T5A C:1CC A:3vIoM4?*F%wUo/lwxdP͌hșXO0R^bdbPHx ߣ5876tx@.0F:z ܬ-3!f=ښy 1wѶ95nN^|ϫf<&'SaHP2'6.ysU\羸1nmsݙ ڴ`1k':^{{K?xOT3RŶէLjE4K3vmwټ5zt;ϭ794ώ$xyJbn =0h}b+@M{V_"|Ti wdoPV{rQ<]O qj!u_{P2gL4HrNs$S ak1cvNrJA (*(PU\N dN 0'fq i\b5X.dNgBuHpB(=%,Bp7Ǎ`t&za\g{;G]Jm+ZLN5BNOo9q{]0+zjx#9Esa(fy v?Qug| ыZ;캣P*ò .qfI_Pm$IIJ@(C4YǍt4~zskρG *LD92FtVg)-2aP*@2 a܆CA "K3e -kt@2{-K%QZDEienPI-iF'A)] nG^4(67e!Hc$^5I撫0#AonIf~XB5 HZ-*-fe ~r̖m\| _Y|j&,<`,?a5s&cˎhUת+ [w\H (ʼn"_; P3Y\xfK);W_-^0 0lؔG[2L0E֬v97Q\D#EeB4c@"qC7\= Y=Yfϐ{sд|? P P<ܠs_zTTEa6Gi]4fOmn3q<8kT _NmSU&μr D #@ BpwzzК_HyBSJYBA8U!BOq0 0M`¥]7y!_ֶ֬_k@d %!C>۱ӸY/׊ ̕0-moʜj>iM`PnMǠ.t'Xz!۞E9 ӧMk7Qߘ\).Xy0 }dWRz=!d:c(KQ5BI.?iA d@o\`{<4E۳'MU9cvpݵ0Dt,Y>!F`F0 DdPZ\zpH˕#wlMOŧ6D0MxF:6`ZafmRncib߄<U5\Ln- (ʅ׀s ʁP8a;B!IX6mqX6rV<&LbJ)KOPB;ta(8p8mH`}?31cvrngZ9 8NcpÉع;MtpS"8d|9$D&pM=F!RyBG&(?okB'2YAsol(c9kF]D0IB_7| L#qˏ \PJF8PTz<^eؘFBC=B/cmnu.ysc&;&< χx'BƮƾW^Ks9'˘cg/U\E)`!7xzn,=|#!mwF׭O1U+7<-XTDP%w,86afb,lmEF-krj,1g,lI<, yz%F5w#rwݙd7mBUBV pdžee 8!Kf۟ٱ:|L}Ʊ6_U%`B)a4:7u @MaSn,N 5p X+,3 B[K Ap kAj,YNxM(o/nu=0AA{hGPn680`. *׺UW8vf t.B& 2Eg(Xq~A)EG`k" JjAg_ 1!,3 L#X6SsSz>GIr0Q{ZUuPl6P z._%v&Hnhz7eN^S OE3׾X+*P&3 . ~ Dwo@aɦ#HJ2Te`;>Fqb0Qۻ:rs1 JEj#cz}烀C@6HR୪Kݨyh7!A,!F:S[$B@Xӯ1O,t}rE>Ol,oFoGU-@TP&* I `el ԡ(_Vgϩ&)D{}؆ȤiB@AZ!*ތpŕ=^ABH<f~K)#s}˟8QG`(H9;&d`8m&߲u70%PV | W$ BSˆ}.AErd]+kxq( cdtmsU/%sDȨ]R% JǺtF곬{c4ed3t_y2R_p,SylX W =mY{'v݇_[O#pdiؖB;L1 DAo? _T$"Ǐ#GkK]8}1zDهLNNR^[t)*W݈Hlsdte!|{2Wh z$-2r1 kPD&*loJ 48G78xl8 ZvINzE_ A-sT_xIzѓ; |Om+ӈsoazۢ]{#_\K>Iu늗~=!?\N߰'I& B3A(yGd(n}v/<j|{Yl9vƥ:ߟ(ù#ݗ$:N6p"mٖClQQ8SxdCck'ݹt}sO_:q}Ǧ֖*KAM ~~G-/vʋ pgz%SjLȀex?}wɚ;NU֪+Jo, -/-.nTv̩U夢$93Ha߿Iρ#' gogglesmm-0.12.7/extra/gogglesmm.svg0000644000175000001440000015524711551134365016154 0ustar sxjusers image/svg+xml gogglesmm-0.12.7/src/0000755000175000001440000000000012063217121013067 5ustar sxjusersgogglesmm-0.12.7/src/GMTrackList.cpp0000644000175000001440000014273611573756352015757 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Icon List Widget (under LGPL3) * * Copyright (C) 1999,2010 by Jeroen van der Zijp. All Rights Reserved. * * --- * * Modifications * * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include "gmdefs.h" #include #include "GMTrackList.h" #include "GMTrackItem.h" #include "GMList.h" #include "GMSource.h" #include "GMTrackView.h" #include "GMPlayerManager.h" #include "GMIconTheme.h" #include "GMTrackDatabase.h" #include "GMDatabaseSource.h" #include "GMPlayListSource.h" #define SIDE_SPACING 4 // Left or right spacing between items #define DETAIL_TEXT_SPACING 2 // Spacing between text and icon in detail icon mode #define MINI_TEXT_SPACING 2 // Spacing between text and icon in mini icon mode #define BIG_LINE_SPACING 6 // Line spacing in big icon mode #define BIG_TEXT_SPACING 2 // Spacing between text and icon in big icon mode #define ITEM_SPACE 128 // Default space for item #define SELECT_MASK (TRACKLIST_EXTENDEDSELECT|TRACKLIST_SINGLESELECT|TRACKLIST_BROWSESELECT|TRACKLIST_MULTIPLESELECT) #define TRACKLIST_MASK (SELECT_MASK) #define ICON_WIDTH 10 #define ICON_HEIGHT 15 // Set or kill focus void GMTrackItem::setFocus(FXbool focus){ if(focus) state|=FOCUS; else state&=~FOCUS; } // Select or deselect item void GMTrackItem::setSelected(FXbool selected){ if(selected) state|=SELECTED; else state&=~SELECTED; } // Icon is draggable void GMTrackItem::setDraggable(FXbool draggable){ if(draggable) state|=DRAGGABLE; else state&=~DRAGGABLE; } // Map FXDEFMAP(GMTrackList) GMTrackListMap[]={ FXMAPFUNC(SEL_PAINT,0,GMTrackList::onPaint), FXMAPFUNC(SEL_MOTION,0,GMTrackList::onMotion), FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,GMTrackList::onLeftBtnPress), FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,GMTrackList::onLeftBtnRelease), FXMAPFUNC(SEL_RIGHTBUTTONPRESS,0,GMTrackList::onRightBtnPress), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,0,GMTrackList::onRightBtnRelease), FXMAPFUNC(SEL_TIMEOUT,GMTrackList::ID_AUTOSCROLL,GMTrackList::onAutoScroll), FXMAPFUNC(SEL_TIMEOUT,GMTrackList::ID_TIPTIMER,GMTrackList::onTipTimer), FXMAPFUNC(SEL_UNGRABBED,0,GMTrackList::onUngrabbed), FXMAPFUNC(SEL_KEYPRESS,0,GMTrackList::onKeyPress), FXMAPFUNC(SEL_KEYRELEASE,0,GMTrackList::onKeyRelease), FXMAPFUNC(SEL_ENTER,0,GMTrackList::onEnter), FXMAPFUNC(SEL_LEAVE,0,GMTrackList::onLeave), FXMAPFUNC(SEL_FOCUSIN,0,GMTrackList::onFocusIn), FXMAPFUNC(SEL_FOCUSOUT,0,GMTrackList::onFocusOut), FXMAPFUNC(SEL_CLICKED,0,GMTrackList::onClicked), FXMAPFUNC(SEL_DOUBLECLICKED,0,GMTrackList::onDoubleClicked), FXMAPFUNC(SEL_TRIPLECLICKED,0,GMTrackList::onTripleClicked), FXMAPFUNC(SEL_COMMAND,0,GMTrackList::onCommand), FXMAPFUNC(SEL_QUERY_TIP,0,GMTrackList::onQueryTip), FXMAPFUNC(SEL_QUERY_HELP,0,GMTrackList::onQueryHelp), FXMAPFUNC(SEL_COMMAND,GMTrackList::ID_HEADER,GMTrackList::onCmdHeader), FXMAPFUNC(SEL_UPDATE,GMTrackList::ID_HEADER,GMTrackList::onUpdHeader), FXMAPFUNC(SEL_CHANGED,GMTrackList::ID_HEADER,GMTrackList::onChgHeader), FXMAPFUNC(SEL_CLICKED,GMTrackList::ID_HEADER,GMTrackList::onClkHeader), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackList::ID_HEADER,GMTrackList::onHeaderRightBtnRelease), FXMAPFUNC(SEL_COMMAND,GMTrackList::ID_SELECT_ALL,GMTrackList::onCmdSelectAll), FXMAPFUNC(SEL_COMMAND,GMTrackList::ID_DESELECT_ALL,GMTrackList::onCmdDeselectAll), FXMAPFUNC(SEL_COMMAND,GMTrackList::ID_SELECT_INVERSE,GMTrackList::onCmdSelectInverse), FXMAPFUNC(SEL_COMMAND,FXWindow::ID_SETVALUE,GMTrackList::onCmdSetValue), FXMAPFUNC(SEL_COMMAND,FXWindow::ID_SETINTVALUE,GMTrackList::onCmdSetIntValue), FXMAPFUNC(SEL_COMMAND,FXWindow::ID_GETINTVALUE,GMTrackList::onCmdGetIntValue), }; // Object implementation FXIMPLEMENT(GMTrackList,FXScrollArea,GMTrackListMap,ARRAYNUMBER(GMTrackListMap)) /*******************************************************************************/ // Serialization GMTrackList::GMTrackList(){ flags|=FLAG_ENABLED; header=(FXHeader*)-1L; anchor=-1; current=-1; extent=-1; cursor=-1; viewable=-1; active=-1; font=(FXFont*)-1L; activeFont=(FXFont*)-1L; sortfunc=NULL; textColor=0; selbackColor=0; seltextColor=0; rowColor=0; activeColor=0; activeTextColor=0; lineHeight=1; anchorx=0; anchory=0; currentx=0; currenty=0; grabx=0; graby=0; state=false; sortMethod=HEADER_DEFAULT; } // Icon List GMTrackList::GMTrackList(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h):FXScrollArea(p,opts,x,y,w,h){ flags|=FLAG_ENABLED; header=new GMHeader(this,this,GMTrackList::ID_HEADER,HEADER_TRACKING|HEADER_BUTTON|HEADER_RESIZE|FRAME_LINE); target=tgt; message=sel; anchor=-1; current=-1; extent=-1; cursor=-1; viewable=-1; active=-1; font=getApp()->getNormalFont(); activeFont=font; sortfunc=NULL; textColor=getApp()->getForeColor(); selbackColor=getApp()->getSelbackColor(); seltextColor=getApp()->getSelforeColor(); rowColor=backColor; activeColor=backColor; activeTextColor=textColor; lineHeight=1; anchorx=0; anchory=0; currentx=0; currenty=0; grabx=0; graby=0; state=false; sortMethod=HEADER_DEFAULT; GMScrollArea::replaceScrollbars(this); } // Create window void GMTrackList::create(){ FXScrollArea::create(); font->create(); } void GMTrackList::markUnsorted() { sortMethod=HEADER_DEFAULT; sortfunc=NULL; } // Detach window void GMTrackList::detach(){ FXScrollArea::detach(); font->detach(); } // If window can have focus #if FOXVERSION < FXVERSION(1,7,0) bool GMTrackList::canFocus() const { return true; } #else FXbool GMTrackList::canFocus() const { return true; } #endif // Into focus chain void GMTrackList::setFocus(){ FXScrollArea::setFocus(); setDefault(TRUE); } // Out of focus chain void GMTrackList::killFocus(){ FXScrollArea::killFocus(); setDefault(MAYBE); } // Propagate size change void GMTrackList::recalc(){ FXScrollArea::recalc(); flags|=FLAG_RECALC; cursor=-1; } #if FOXVERSION < FXVERSION(1,7,0) FXint GMTrackList::getViewportHeight(){ return height-header->getDefaultHeight(); } #else // Return visible area y position FXint GMTrackList::getVisibleY() const { return header->getHeight(); } // Return visible area height FXint GMTrackList::getVisibleHeight() const { return height-header->getHeight()-horizontal->getHeight(); } #endif // Move content void GMTrackList::moveContents(FXint x,FXint y){ #if FOXVERSION < FXVERSION(1,7,0) FXint dx=x-pos_x; FXint dy=y-pos_y; FXint top=0; pos_x=x; pos_y=y; top=header->getDefaultHeight(); header->setPosition(x); scroll(0,top,viewport_w,viewport_h,dx,dy); #else FXScrollArea::moveContents(x,y); header->setPosition(x); #endif } // Recompute interior void GMTrackList::recompute(){ lineHeight=FXMAX(GMIconTheme::instance()->getSmallSize(),(4+font->getFontHeight())); flags&=~FLAG_RECALC; } // Determine content width of icon list FXint GMTrackList::getContentWidth(){ if(flags&FLAG_RECALC) recompute(); return header->getTotalSize(); } // Determine content height of icon list FXint GMTrackList::getContentHeight(){ if(flags&FLAG_RECALC) recompute(); return items.no()*lineHeight; } // Recalculate layout void GMTrackList::layout(){ #if FOXVERSION < FXVERSION(1,7,0) // Update scroll bars FXScrollArea::layout(); // In detail mode header->position(0,0,viewport_w,header->getDefaultHeight()); header->show(); // Set line size vertical->setLine(lineHeight); horizontal->setLine(header->getTotalSize()); // We were supposed to make this item viewable if(0<=viewable){ makeItemVisible(viewable); } // Force repaint update(); flags&=~FLAG_DIRTY; #else FXint hh=header->getDefaultHeight(); // Place scroll bars placeScrollBars(width,height-hh); // Place header control header->position(0,0,width,hh); // Set line size vertical->setLine(lineHeight); horizontal->setLine(header->getTotalSize()); // We were supposed to make this item viewable if(0<=viewable){ makeItemVisible(viewable); } // Force repaint update(); // Clean flags&=~FLAG_DIRTY; #endif } // Header changed but content size didn't long GMTrackList::onChgHeader(FXObject*,FXSelector,void*){ return 1; } // Header subdivision resize has been requested; // we want to set the width of the header column // to that of the widest item. long GMTrackList::onClkHeader(FXObject*,FXSelector,void* ptr){ register FXint hi=(FXint)(FXival)ptr; register FXint i,tw,w,nw=0,type; FXuint justify; FXint max; const FXString * textptr; FXString text; type=getHeaderData(hi)->type; for(i=0;igetColumnData(type,text,justify,max); /* if (justify) { tw=font->getTextWidth(*textptr); w=FXMAX(tw,max)+SIDE_SPACING+2; } else */ if (textptr && !textptr->empty()){ tw=font->getTextWidth(*textptr); w=tw+SIDE_SPACING+2; } if(w>nw) nw=w; } if (hi==0) { nw+=ICON_WIDTH+DETAIL_TEXT_SPACING+SIDE_SPACING/2; } // Set new header width if(nw>0 && nw!=header->getItemSize(hi)){ header->setItemSize(hi,nw); flags&=~FLAG_RECALC; } return 1; } long GMTrackList::onHeaderRightBtnRelease(FXObject*,FXSelector,void*ptr){ if (target) target->handle(this,FXSEL(SEL_RIGHTBUTTONRELEASE,message+1),ptr); return 1; }; long GMTrackList::onCmdHeader(FXObject*,FXSelector,void*ptr){ GMColumn * data = getHeaderData((FXuint)(FXival)ptr); if (data) { if (data->type==sortMethod) { if (sortfunc==data->ascending) sortfunc=data->descending; else sortfunc=data->ascending; } else { sortMethod=data->type; sortfunc=data->ascending; } if (sortfunc) GMPlayerManager::instance()->getTrackView()->sortTracks(); } return 1; } long GMTrackList::onUpdHeader(FXObject*,FXSelector,void*){ GMColumn * data; for (FXint i=0;igetNumItems();i++){ data = getHeaderData(i); if (data && sortMethod==data->type) { #if FOXVERSION < FXVERSION(1,7,0) if (sortfunc==data->ascending) header->setArrowDir(i,FALSE); else header->setArrowDir(i,TRUE); } else { header->setArrowDir(i,MAYBE); } #else if (sortfunc==data->ascending) header->setArrowDir(i,FXHeaderItem::ARROW_DOWN); else header->setArrowDir(i,FXHeaderItem::ARROW_UP); } else { header->setArrowDir(i,FXHeaderItem::ARROW_NONE); } #endif } return 1; } void GMTrackList::appendHeader(const FXString & label,FXint size,GMColumn * data){ GMColumn * c; for (FXint i=0;igetNumItems();i++){ c = getHeaderData(i); if (data->index < c->index){ header->insertItem(i,label,NULL,size,data); return; } } header->appendItem(label,NULL,size,data); } // Remove header caption void GMTrackList::removeHeader(FXint index){ if(index<0 || header->getNumItems()<=index){ fxerror("%s::removeHeader: index out of range.\n",getClassName()); } header->removeItem(index); } // Return number of headers FXint GMTrackList::getNumHeaders() const { return header->getNumItems(); } /// Remove all headers void GMTrackList::clearHeaders() { header->clearItems(); } /// Save header configuration void GMTrackList::saveHeaders() { GMColumn * column = NULL; for (FXint i=0;igetNumItems();i++){ column = getHeaderData(i); FXASSERT(column); column->size = header->getItemSize(i); //column->index = i; } } // True if item is selected FXbool GMTrackList::isItemSelected(FXint index) const { if(index<0 || items.no()<=index){ fxerror("%s::isItemSelected: index out of range.\n",getClassName()); } return items[index]->isSelected(); } // True if item is current FXbool GMTrackList::isItemCurrent(FXint index) const { if(index<0 || items.no()<=index){ fxerror("%s::isItemCurrent: index out of range.\n",getClassName()); } return index==current; } // True if item (partially) visible FXbool GMTrackList::isItemVisible(FXint index) const { register FXbool vis=false; register FXint y,hh; if(index<0 || items.no()<=index){ fxerror("%s::isItemVisible: index out of range.\n",getClassName()); } hh=header->getDefaultHeight(); y=pos_y+hh+index*lineHeight; #if FOXVERSION < FXVERSION(1,7,0) if(hhgetDefaultHeight(); y=hh+index*lineHeight; if(py+y+lineHeight >= vh+hh) py=hh+vh-y-lineHeight; if(py+y <= hh) py=hh-y; // Scroll into view setPosition(px,py); // Done it viewable=-1; } } } // Get item at position x,y FXint GMTrackList::getItemAt(FXint x,FXint y) const { register FXint index; y-=pos_y; x-=pos_x; y-=header->getDefaultHeight(); index=y/lineHeight; if(index<0 || index>=items.no()) return -1; return index; } // Did we hit the item, and which part of it did we hit FXint GMTrackList::hitItem(FXint index,FXint /*x*/,FXint /*y*/,FXint /*ww*/,FXint /*hh*/) const { #if 0 FXint ix,iy,r,c,hit=0; if(0<=index && indexgetDefaultHeight(); // r=index; // c=0; // ix=header->getTotalSize()*c; // iy=lineHeight*r; hit=2; //FIXME items[index]->hitItem(this,x-ix,y-iy,ww,hh); } #endif FXint hit=0; if(0<=index && indexgetDefaultHeight()+index*lineHeight,width,lineHeight); } } // Select one item FXbool GMTrackList::selectItem(FXint index,FXbool notify){ if(index<0 || items.no()<=index){ fxerror("%s::selectItem: index out of range.\n",getClassName()); } if(!items[index]->isSelected()){ switch(options&SELECT_MASK){ case TRACKLIST_SINGLESELECT: case TRACKLIST_BROWSESELECT: killSelection(notify); case TRACKLIST_EXTENDEDSELECT: case TRACKLIST_MULTIPLESELECT: items[index]->setSelected(true); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)index);} break; } return true; } return false; } // Deselect one item FXbool GMTrackList::deselectItem(FXint index,FXbool notify){ if(index<0 || items.no()<=index){ fxerror("%s::deselectItem: index out of range.\n",getClassName()); } if(items[index]->isSelected()){ switch(options&SELECT_MASK){ case TRACKLIST_EXTENDEDSELECT: case TRACKLIST_MULTIPLESELECT: case TRACKLIST_SINGLESELECT: items[index]->setSelected(false); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)index);} break; } return true; } return false; } // Toggle one item FXbool GMTrackList::toggleItem(FXint index,FXbool notify){ if(index<0 || items.no()<=index){ fxerror("%s::toggleItem: index out of range.\n",getClassName()); } switch(options&SELECT_MASK){ case TRACKLIST_BROWSESELECT: if(!items[index]->isSelected()){ killSelection(notify); items[index]->setSelected(true); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)index);} } break; case TRACKLIST_SINGLESELECT: if(!items[index]->isSelected()){ killSelection(notify); items[index]->setSelected(true); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)index);} } else{ items[index]->setSelected(false); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)index);} } break; case TRACKLIST_EXTENDEDSELECT: case TRACKLIST_MULTIPLESELECT: if(!items[index]->isSelected()){ items[index]->setSelected(true); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)index);} } else{ items[index]->setSelected(false); updateItem(index); if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)index);} } break; } return true; } // Select items in rectangle FXbool GMTrackList::selectInRectangle(FXint x,FXint y,FXint w,FXint h,FXbool notify){ register FXint index; register FXbool changed=false; for(index=0; indexisSelected()){ items[i]->setSelected(true); updateItem(i); changes=true; if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)i);} } } // extent===anchor---item // extent===item-----anchor else if(i1==extent){ if(items[i]->isSelected()){ items[i]->setSelected(false); updateItem(i); changes=true; if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)i);} } } } // Second segment for(i=i2+1; i<=i3; i++){ // extent---anchor===item // anchor---extent===item if(i3==index){ if(!items[i]->isSelected()){ items[i]->setSelected(true); updateItem(i); changes=true; if(notify && target){target->tryHandle(this,FXSEL(SEL_SELECTED,message),(void*)(FXival)i);} } } // item-----anchor===extent // anchor---item=====extent else if(i3==extent){ if(items[i]->isSelected()){ items[i]->setSelected(false); updateItem(i); changes=true; if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)i);} } } } extent=index; } return changes; } // Kill selection FXbool GMTrackList::killSelection(FXbool notify){ register FXbool changes=false; register FXint i; for(i=0; iisSelected()){ items[i]->setSelected(false); updateItem(i); changes=true; if(notify && target){target->tryHandle(this,FXSEL(SEL_DESELECTED,message),(void*)(FXival)i);} } } return changes; } // Update value from a message long GMTrackList::onCmdSetValue(FXObject*,FXSelector,void* ptr){ setCurrentItem((FXint)(FXival)ptr); return 1; } // Obtain value from list long GMTrackList::onCmdGetIntValue(FXObject*,FXSelector,void* ptr){ *((FXint*)ptr)=getCurrentItem(); return 1; } // Update value from a message long GMTrackList::onCmdSetIntValue(FXObject*,FXSelector,void* ptr){ setCurrentItem(*((FXint*)ptr)); return 1; } // Start motion timer while in this window long GMTrackList::onEnter(FXObject* sender,FXSelector sel,void* ptr){ FXScrollArea::onEnter(sender,sel,ptr); getApp()->addTimeout(this,ID_TIPTIMER,getApp()->getMenuPause()); cursor=-1; return 1; } // Stop motion timer when leaving window long GMTrackList::onLeave(FXObject* sender,FXSelector sel,void* ptr){ FXScrollArea::onLeave(sender,sel,ptr); getApp()->removeTimeout(this,ID_TIPTIMER); cursor=-1; return 1; } // We timed out, i.e. the user didn't move for a while long GMTrackList::onTipTimer(FXObject*,FXSelector,void*){ FXTRACE((250,"%s::onTipTimer %p\n",getClassName(),this)); flags|=FLAG_TIP; return 1; } // We were asked about tip text long GMTrackList::onQueryTip(FXObject* sender,FXSelector sel,void* ptr){ if(FXScrollArea::onQueryTip(sender,sel,ptr)) return 1; /* FIXME if((flags&FLAG_TIP) && (0<=cursor)){ FXString string=items[cursor]->getText().section('\t',0); sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&string); return 1; } */ return 0; } // We were asked about status text long GMTrackList::onQueryHelp(FXObject* sender,FXSelector sel,void* ptr){ if(FXScrollArea::onQueryHelp(sender,sel,ptr)) return 1; if((flags&FLAG_HELP) && !help.empty()){ sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&help); return 1; } return 0; } // Gained focus long GMTrackList::onFocusIn(FXObject* sender,FXSelector sel,void* ptr){ FXScrollArea::onFocusIn(sender,sel,ptr); if(0<=current){ FXASSERT(currentsetFocus(true); updateItem(current); } return 1; } // Lost focus long GMTrackList::onFocusOut(FXObject* sender,FXSelector sel,void* ptr){ FXScrollArea::onFocusOut(sender,sel,ptr); if(0<=current){ FXASSERT(currentsetFocus(false); updateItem(current); } return 1; } // Draw item list long GMTrackList::onPaint(FXObject*,FXSelector,void* ptr){ register FXint rlo,rhi,dw,index,vw,y; FXEvent* event=(FXEvent*)ptr; FXDCWindow dc(this,event); // Draw nothing if (header->getNumItems()==0) { dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); return 1; } // Set font dc.setFont(font); // Calculate stipple width dw=font->getTextWidth(UTF8_ELLIPSIS,3); // Exposed rows rlo=(event->rect.y-pos_y-header->getDefaultHeight())/lineHeight; rhi=(event->rect.y+event->rect.h-pos_y-header->getDefaultHeight())/lineHeight; if(rlo<0) rlo=0; if(rhi>=items.no()) rhi=items.no()-1; #if FOXVERSION < FXVERSION(1,7,0) vw = getViewportWidth(); #else vw = getVisibleWidth(); #endif // Repaint the items y=pos_y+rlo*lineHeight+header->getDefaultHeight(); for(index=rlo; index<=rhi; index++,y+=lineHeight){ if (active==index) { dc.setForeground(activeColor); dc.setFont(activeFont); } else if (index%2) dc.setForeground(rowColor); else dc.setForeground(backColor); draw(dc,event,index,pos_x,y,vw,lineHeight,dw); if (active==index) dc.setFont(font); } // Background below y=pos_y+(rhi+1)*lineHeight+header->getDefaultHeight(); if(yrect.y+event->rect.h){ dc.setForeground(backColor); dc.fillRectangle(event->rect.x,y,event->rect.w,event->rect.y+event->rect.h-y); } return 1; } void GMTrackList::draw(FXDC& dc,FXEvent *,FXint index,FXint x,FXint y,FXint w,FXint h,FXint dw) const { register FXint iw=0,ih=0,tw=0,th=0,yt,hi,drw,space,used,xx,type; FXString text; const FXString * textptr; FXint max=50; FXuint justify; FXIcon * icon=NULL; /// Get Icon Size iw=ih=GMIconTheme::instance()->getSmallSize(); if(header->getNumItems()==0) return; #if 0 if (GMPlayerManager::instance()->getPlayQueue() && GMPlayerManager::instance()->getPlayQueue()->hasTrack(items[index]->getId())){ icon = GMIconTheme::instance()->icon_playqueue; icon->create(); } #endif /// Draw background if(items[index]->isSelected()){ if (active==index) icon = GMIconTheme::instance()->icon_play;//selectedIcon; dc.setForeground(getSelBackColor()); dc.fillRectangle(0,y,w,h); } else{ if (active==index) icon = GMIconTheme::instance()->icon_play; //activeIcon; dc.fillRectangle(0,y,w,h); } /// Draw Focus if(items[index]->hasFocus()){ dc.drawFocusRectangle(x+1,y+1,getHeader()->getTotalSize()-2,h-2); } /// Draw Icon xx=x+SIDE_SPACING/2; if(icon){ dc.setClipRectangle(x,y,header->getItemSize(0),h); dc.drawIcon(icon,xx,y+(h-ih)/2); dc.clearClipRectangle(); } xx+=iw+DETAIL_TEXT_SPACING; /// Draw Text th=dc.getFont()->getFontHeight(); yt=y+(h-th-4)/2; if(items[index]->isSelected()) dc.setForeground(getSelTextColor()); else if (active==index) dc.setForeground(getActiveTextColor()); else dc.setForeground(getTextColor()); used=iw+DETAIL_TEXT_SPACING+SIDE_SPACING/2; #if FOXVERSION < FXVERSION(1,7,0) for(hi=0;higetNumItems()&& xx<=w; hi++){ #else for(hi=0;higetNumItems()&& xx<=w+getVisibleX(); hi++){ #endif space=header->getItemSize(hi)-used; #if FOXVERSION < FXVERSION(1,7,0) if (xx+space>=0){ #else if (xx+space>=getVisibleX()){ #endif type=getHeaderType(hi); textptr=items[index]->getColumnData(type,text,justify,max); if (textptr) { drw=textptr->length(); tw=dc.getFont()->getTextWidth(*textptr); if(tw>space-4){ while((tw=dc.getFont()->getTextWidth(textptr->text(),drw))+dw>space-4 && drw>1) drw=textptr->dec(drw); dc.setClipRectangle(xx,y,space,h); dc.drawText(xx+2,yt+dc.getFont()->getFontAscent()+2,textptr->text(),drw); dc.drawText(xx+tw+2,yt+dc.getFont()->getFontAscent()+2,UTF8_ELLIPSIS,3); dc.clearClipRectangle(); } else if (justify==0 || (justify && max>space)) { dc.drawText(xx+2,yt+dc.getFont()->getFontAscent()+2,textptr->text(),drw); } else if (justify==COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED) { dc.drawText(xx+2+max-tw,yt+dc.getFont()->getFontAscent()+2,text.text(),drw); } else if (justify==COLUMN_JUSTIFY_CENTER_RIGHT_ALIGNED){ dc.drawText(xx+((space/2)-(max/2))+(max-tw),yt+dc.getFont()->getFontAscent()+2,textptr->text(),drw); } else if (justify==COLUMN_JUSTIFY_RIGHT){ dc.drawText(xx+(space-tw)-2,yt+dc.getFont()->getFontAscent()+2,textptr->text(),drw); } else { dc.drawText(xx+2,yt+dc.getFont()->getFontAscent()+2,textptr->text(),drw); } } } xx+=space; used=0; } } // Select all items long GMTrackList::onCmdSelectAll(FXObject*,FXSelector,void*){ for(int i=0; i0; h/=3){ for(i=h+1;i<=items.no();i++){ v=items[i-1]; j=i; while(j>h && sortfunc(items[j-h-1],v)>0){ items[j-1]=items[j-h-1]; exch=true; j-=h; } items[j-1]=v; } } if(0<=current){ for(i=0; isetFocus(false); updateItem(current); } } current=index; // Activate new item if(0<=current){ // No visible change if it doen't have the focus if(hasFocus()){ items[current]->setFocus(true); updateItem(current); } } // Notify item change if(notify && target){target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)current);} } // In browse selection mode, select item if((options&SELECT_MASK)==TRACKLIST_BROWSESELECT && 0<=current ){ selectItem(current,notify); } } // Set anchor item void GMTrackList::setAnchorItem(FXint index){ if(index<-1 || items.no()<=index){ fxerror("%s::setAnchorItem: index out of range.\n",getClassName()); } anchor=index; extent=index; } // Set active item void GMTrackList::setActiveItem(FXint i) { active=i; if (items.no()) { if (i>=0) makeItemVisible(i); update(); } } // Key Press long GMTrackList::onKeyPress(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXint index=current; flags&=~FLAG_TIP; if(!isEnabled()) return 0; if(target && target->tryHandle(this,FXSEL(SEL_KEYPRESS,message),ptr)) return 1; switch(event->code){ case KEY_Control_L: case KEY_Control_R: case KEY_Shift_L: case KEY_Shift_R: case KEY_Alt_L: case KEY_Alt_R: if(flags&FLAG_DODRAG){handle(this,FXSEL(SEL_DRAGGED,0),ptr);} return 1; case KEY_Page_Up: case KEY_KP_Page_Up: setPosition(pos_x,pos_y+verticalScrollBar()->getPage()); return 1; case KEY_Page_Down: case KEY_KP_Page_Down: setPosition(pos_x,pos_y-verticalScrollBar()->getPage()); return 1; case KEY_Right: case KEY_KP_Right: setPosition(pos_x-10,pos_y); return 1; goto hop; case KEY_Left: case KEY_KP_Left: setPosition(pos_x+10,pos_y); return 1; goto hop; case KEY_Up: case KEY_KP_Up: index-=1; goto hop; case KEY_Down: case KEY_KP_Down: index+=1; goto hop; case KEY_Home: case KEY_KP_Home: index=0; goto hop; case KEY_End: case KEY_KP_End: index=items.no()-1; hop: if(0<=index && indexstate&SHIFTMASK){ if(0<=anchor){ selectItem(anchor,true); extendSelection(index,true); } else{ selectItem(index,true); } } else if(!(event->state&CONTROLMASK)){ killSelection(true); selectItem(index,true); setAnchorItem(index); } } } handle(this,FXSEL(SEL_CLICKED,0),(void*)(FXival)current); if(0<=current){ handle(this,FXSEL(SEL_COMMAND,0),(void*)(FXival)current); } return 1; case KEY_space: case KEY_KP_Space: if(0<=current){ switch(options&SELECT_MASK){ case TRACKLIST_EXTENDEDSELECT: if(event->state&SHIFTMASK){ if(0<=anchor){ selectItem(anchor,true); extendSelection(current,true); } else{ selectItem(current,true); } } else if(event->state&CONTROLMASK){ toggleItem(current,true); } else{ killSelection(true); selectItem(current,true); } break; case TRACKLIST_MULTIPLESELECT: case TRACKLIST_SINGLESELECT: toggleItem(current,true); break; } setAnchorItem(current); } handle(this,FXSEL(SEL_CLICKED,0),(void*)(FXival)current); if(0<=current){ handle(this,FXSEL(SEL_COMMAND,0),(void*)(FXival)current); } return 1; case KEY_Return: case KEY_KP_Enter: handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)(FXival)current); if(0<=current){ handle(this,FXSEL(SEL_COMMAND,0),(void*)(FXival)current); } return 1; default: break; } return 0; } // Key Release long GMTrackList::onKeyRelease(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; if(!isEnabled()) return 0; if(target && target->tryHandle(this,FXSEL(SEL_KEYRELEASE,message),ptr)) return 1; switch(event->code){ case KEY_Shift_L: case KEY_Shift_R: case KEY_Control_L: case KEY_Control_R: case KEY_Alt_L: case KEY_Alt_R: if(flags&FLAG_DODRAG){handle(this,FXSEL(SEL_DRAGGED,0),ptr);} return 1; } return 0; } // Autoscrolling timer long GMTrackList::onAutoScroll(FXObject* sender,FXSelector sel,void* ptr){ // Scroll the content FXScrollArea::onAutoScroll(sender,sel,ptr); // Content scrolled, so perhaps something else under cursor if(flags&FLAG_DODRAG){ handle(this,FXSEL(SEL_DRAGGED,0),ptr); return 1; } return 0; } // Mouse moved long GMTrackList::onMotion(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXint oldcursor=cursor; FXuint flg=flags; // Kill the tip flags&=~FLAG_TIP; // Kill the tip timer getApp()->removeTimeout(this,ID_TIPTIMER); // Right mouse scrolling if(flags&FLAG_SCROLLING){ setPosition(event->win_x-grabx,event->win_y-graby); return 1; } // Drag and drop mode if(flags&FLAG_DODRAG){ if(startAutoScroll(event,true)) return 1; handle(this,FXSEL(SEL_DRAGGED,0),ptr); return 1; } // Tentative drag and drop if(flags&FLAG_TRYDRAG){ if(event->moved){ flags&=~FLAG_TRYDRAG; if(handle(this,FXSEL(SEL_BEGINDRAG,0),ptr)){ flags|=FLAG_DODRAG; } } return 1; } // Reset tip timer if nothing's going on getApp()->addTimeout(this,ID_TIPTIMER,getApp()->getMenuPause()); // Get item we're over cursor=getItemAt(event->win_x,event->win_y); // Force GUI update only when needed return (cursor!=oldcursor)||(flg&FLAG_TIP); } // Pressed a button long GMTrackList::onLeftBtnPress(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXint index; flags&=~FLAG_TIP; handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr); if(isEnabled()){ grab(); flags&=~FLAG_UPDATE; // First change callback if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) return 1; // Locate item index=getItemAt(event->win_x,event->win_y); // No item if(index<0){ return 1; } // Previous selection state state=items[index]->isSelected(); // Change current item setCurrentItem(index,true); // Change item selection switch(options&SELECT_MASK){ case TRACKLIST_EXTENDEDSELECT: if(event->state&SHIFTMASK){ if(0<=anchor){ selectItem(anchor,true); extendSelection(index,true); } else{ selectItem(index,true); setAnchorItem(index); } } else if(event->state&CONTROLMASK){ if(!state) selectItem(index,true); setAnchorItem(index); } else{ if(!state){ killSelection(true); selectItem(index,true); } setAnchorItem(index); } break; case TRACKLIST_MULTIPLESELECT: case TRACKLIST_SINGLESELECT: if(!state) selectItem(index,true); break; } // Are we dragging? if(state && items[index]->isSelected() && items[index]->isDraggable()){ flags|=FLAG_TRYDRAG; } flags|=FLAG_PRESSED; return 1; } return 0; } // Released button long GMTrackList::onLeftBtnRelease(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXuint flg=flags; if(isEnabled()){ ungrab(); stopAutoScroll(); flags|=FLAG_UPDATE; flags&=~(FLAG_PRESSED|FLAG_TRYDRAG|FLAG_LASSO|FLAG_DODRAG); // First chance callback if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) return 1; // Was dragging if(flg&FLAG_DODRAG){ handle(this,FXSEL(SEL_ENDDRAG,0),ptr); return 1; } // Must have pressed if(flg&FLAG_PRESSED){ // Selection change switch(options&SELECT_MASK){ case TRACKLIST_EXTENDEDSELECT: if(0<=current){ if(event->state&CONTROLMASK){ if(state) deselectItem(current,true); } else if(!(event->state&SHIFTMASK)){ if(state){ killSelection(true); selectItem(current,true); } } } break; case TRACKLIST_MULTIPLESELECT: case TRACKLIST_SINGLESELECT: if(0<=current){ if(state) deselectItem(current,true); } break; } // Scroll to make item visibke makeItemVisible(current); // Update anchor setAnchorItem(current); // Generate clicked callbacks if(event->click_count==1){ handle(this,FXSEL(SEL_CLICKED,0),(void*)(FXival)current); } else if(event->click_count==2){ handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)(FXival)current); } else if(event->click_count==3){ handle(this,FXSEL(SEL_TRIPLECLICKED,0),(void*)(FXival)current); } // Command callback only when clicked on item if(0<=current){ handle(this,FXSEL(SEL_COMMAND,0),(void*)(FXival)current); } } return 1; } return 0; } // Pressed right button long GMTrackList::onRightBtnPress(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; flags&=~FLAG_TIP; handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr); if(isEnabled()){ grab(); flags&=~FLAG_UPDATE; if(target && target->tryHandle(this,FXSEL(SEL_RIGHTBUTTONPRESS,message),ptr)) return 1; flags|=FLAG_SCROLLING; grabx=event->win_x-pos_x; graby=event->win_y-pos_y; return 1; } return 0; } // Released right button long GMTrackList::onRightBtnRelease(FXObject*,FXSelector,void* ptr){ if(isEnabled()){ ungrab(); flags&=~FLAG_SCROLLING; flags|=FLAG_UPDATE; if(target && target->tryHandle(this,FXSEL(SEL_RIGHTBUTTONRELEASE,message),ptr)) return 1; return 1; } return 0; } // The widget lost the grab for some reason long GMTrackList::onUngrabbed(FXObject* sender,FXSelector sel,void* ptr){ FXScrollArea::onUngrabbed(sender,sel,ptr); flags&=~(FLAG_DODRAG|FLAG_LASSO|FLAG_TRYDRAG|FLAG_PRESSED|FLAG_CHANGED|FLAG_SCROLLING); flags|=FLAG_UPDATE; stopAutoScroll(); return 1; } // Command message long GMTrackList::onCommand(FXObject*,FXSelector,void* ptr){ return target && target->tryHandle(this,FXSEL(SEL_COMMAND,message),ptr); } // Clicked in list long GMTrackList::onClicked(FXObject*,FXSelector,void* ptr){ return target && target->tryHandle(this,FXSEL(SEL_CLICKED,message),ptr); } // Double Clicked in list; ptr may or may not point to an item long GMTrackList::onDoubleClicked(FXObject*,FXSelector,void* ptr){ return target && target->tryHandle(this,FXSEL(SEL_DOUBLECLICKED,message),ptr); } // Triple Clicked in list; ptr may or may not point to an item long GMTrackList::onTripleClicked(FXObject*,FXSelector,void* ptr){ return target && target->tryHandle(this,FXSEL(SEL_TRIPLECLICKED,message),ptr); } // Retrieve item GMTrackItem *GMTrackList::getItem(FXint index) const { if(index<0 || items.no()<=index){ fxerror("%s::getItem: index out of range.\n",getClassName()); } return items[index]; } // Replace item with another FXint GMTrackList::setItem(FXint index,GMTrackItem* item,FXbool notify){ // Must have item if(!item){ fxerror("%s::setItem: item is NULL.\n",getClassName()); } // Must be in range if(index<0 || items.no()<=index){ fxerror("%s::setItem: index out of range.\n",getClassName()); } // Notify item will be replaced if(notify && target){target->tryHandle(this,FXSEL(SEL_REPLACED,message),(void*)(FXival)index);} // Copy the state over item->state=items[index]->state; // Delete old delete items[index]; // Add new items[index]=item; // Redo layout recalc(); return index; } // Insert item FXint GMTrackList::insertItem(FXint index,GMTrackItem* item,FXbool notify){ register FXint old=current; // Must have item if(!item){ fxerror("%s::insertItem: item is NULL.\n",getClassName()); } // Must be in range if(index<0 || items.no()=index) anchor++; if(extent>=index) extent++; if(current>=index) current++; if(viewable>=index) viewable++; if(current<0 && items.no()==1) current=0; // Notify item has been inserted if(notify && target){target->tryHandle(this,FXSEL(SEL_INSERTED,message),(void*)(FXival)index);} // Current item may have changed if(old!=current){ if(notify && target){target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)current);} } // Was new item if(0<=current && current==index){ if(hasFocus()){ items[current]->setFocus(true); } if((options&SELECT_MASK)==TRACKLIST_BROWSESELECT){ selectItem(current,notify); } } // Redo layout recalc(); return index; } // Append item FXint GMTrackList::appendItem(GMTrackItem* item,FXbool notify){ return insertItem(items.no(),item,notify); } // Prepend item FXint GMTrackList::prependItem(GMTrackItem* item,FXbool notify){ return insertItem(0,item,notify); } // Move item from oldindex to newindex FXint GMTrackList::moveItem(FXint newindex,FXint oldindex,FXbool notify){ register FXint old=current; GMTrackItem *item; // Must be in range if(newindex<0 || oldindex<0 || items.no()<=newindex || items.no()<=oldindex){ fxerror("%s::moveItem: index out of range.\n",getClassName()); } // Did it change? if(oldindex!=newindex){ // Move item item=items[oldindex]; items.erase(oldindex); items.insert(newindex,item); // Move item down if(newindextryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)current);} } // Redo layout recalc(); } return newindex; } // Extract node from list GMTrackItem* GMTrackList::extractItem(FXint index,FXbool notify){ register GMTrackItem *result; register FXint old=current; // Must be in range if(index<0 || items.no()<=index){ fxerror("%s::extractItem: index out of range.\n",getClassName()); } // Notify item will be deleted if(notify && target){target->tryHandle(this,FXSEL(SEL_DELETED,message),(void*)(FXival)index);} // Extract item result=items[index]; // Remove from list items.erase(index); // Adjust indices if(anchor>index || anchor>=items.no()) anchor--; if(extent>index || extent>=items.no()) extent--; if(current>index || current>=items.no()) current--; if(viewable>index || viewable>=items.no()) viewable--; // Current item has changed if(index<=old){ if(notify && target){target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)current);} } // Deleted current item if(0<=current && index==old){ if(hasFocus()){ items[current]->setFocus(true); } if((options&SELECT_MASK)==TRACKLIST_BROWSESELECT){ selectItem(current,notify); } } // Redo layout recalc(); // Return item return result; } // Remove node from list void GMTrackList::removeItem(FXint index,FXbool notify){ register FXint old=current; // Must be in range if(index<0 || items.no()<=index){ fxerror("%s::removeItem: index out of range.\n",getClassName()); } // Notify item will be deleted if(notify && target){target->tryHandle(this,FXSEL(SEL_DELETED,message),(void*)(FXival)index);} // Delete item delete items[index]; // Remove from list items.erase(index); // Adjust indices if(anchor>index || anchor>=items.no()) anchor--; if(extent>index || extent>=items.no()) extent--; if(current>index || current>=items.no()) current--; if(viewable>index || viewable>=items.no()) viewable--; // Current item has changed if(index<=old){ if(notify && target){target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)current);} } // Deleted current item if(0<=current && index==old){ if(hasFocus()){ items[current]->setFocus(true); } if((options&SELECT_MASK)==TRACKLIST_BROWSESELECT){ selectItem(current,notify); } } // Redo layout recalc(); } // Remove all items void GMTrackList::clearItems(FXbool notify){ register FXint old=current; // Delete items for(FXint index=items.no()-1; 0<=index; index--){ if(notify && target){target->tryHandle(this,FXSEL(SEL_DELETED,message),(void*)(FXival)index);} delete items[index]; } // Free array items.clear(); // Adjust indices current=-1; anchor=-1; extent=-1; viewable=-1; // Current item has changed if(old!=-1){ if(notify && target){target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)-1);} } // Redo layout recalc(); } // Change the font void GMTrackList::setFont(FXFont* fnt){ if(!fnt){ fxerror("%s::setFont: NULL font specified.\n",getClassName()); } if(font!=fnt){ font=fnt; recalc(); update(); } } // Change the font void GMTrackList::setActiveFont(FXFont* fnt){ if(!fnt){ fxerror("%s::setFont: NULL font specified.\n",getClassName()); } if(activeFont!=fnt){ activeFont=fnt; recalc(); update(); } } // Set text color void GMTrackList::setTextColor(FXColor clr){ if(clr!=textColor){ textColor=clr; update(); } } // Set select background color void GMTrackList::setSelBackColor(FXColor clr){ if(clr!=selbackColor){ selbackColor=clr; update(); } } // Set selected text color void GMTrackList::setSelTextColor(FXColor clr){ if(clr!=seltextColor){ seltextColor=clr; update(); } } // Change the row color void GMTrackList::setRowColor(FXColor clr){ if(clr!=rowColor){ rowColor=clr; update(); } } // Change the active color void GMTrackList::setActiveColor(FXColor clr){ if(clr!=activeColor){ activeColor=clr; update(); } } // Change the active text color void GMTrackList::setActiveTextColor(FXColor clr){ if(clr!=activeTextColor){ activeTextColor=clr; } } // Change list style void GMTrackList::setListStyle(FXuint style){ FXuint opts=(options&~TRACKLIST_MASK) | (style&TRACKLIST_MASK); if(options!=opts){ options=opts; recalc(); } } // Get list style FXuint GMTrackList::getListStyle() const { return (options&TRACKLIST_MASK); } // Change help text void GMTrackList::setHelpText(const FXString& text){ help=text; } // Save data void GMTrackList::save(FXStream& store) const { FXScrollArea::save(store); store << header; store << anchor; store << current; store << extent; store << font; store << textColor; store << selbackColor; store << seltextColor; store << lineHeight; store << help; } // Load data void GMTrackList::load(FXStream& store){ FXScrollArea::load(store); store >> header; store >> anchor; store >> current; store >> extent; store >> font; store >> textColor; store >> selbackColor; store >> seltextColor; store >> lineHeight; store >> help; } // Cleanup GMTrackList::~GMTrackList(){ getApp()->removeTimeout(this,ID_TIPTIMER); clearItems(false); header=(FXHeader*)-1L; font=(FXFont*)-1L; activeFont=(FXFont*)-1L; } gogglesmm-0.12.7/src/GMThread.h0000644000175000001440000000342211525430601014676 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTHREAD_H #define GMTHREAD_H class GMThread : public FXThread { public: FXMessageChannel feedback; FXObject * target; protected: volatile FXbool running; protected: virtual FXint run()=0; public: GMThread(FXObject*); /// Cleanup void dispose(); /// Cleanup void dispose_and_join(); virtual ~GMThread(); }; #endif gogglesmm-0.12.7/src/GMPlayer.h0000644000175000001440000001603411525430601014726 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef DVD_XINE #define DVD_XINE class GMTrackDatabase; enum { REPEAT_AB_OFF=0, REPEAT_AB_A, REPEAT_AB_B }; class GMEQBands { public: FXdouble bands[10]; public: GMEQBands(); GMEQBands(FXdouble e0,FXdouble e1,FXdouble e2,FXdouble e3,FXdouble e4,FXdouble e5,FXdouble e6,FXdouble e7,FXdouble e8,FXdouble e9); GMEQBands(const GMEQBands &); FXdouble& operator[](FXint i){ return bands[i]; } const FXdouble& operator[](FXint i) const { return bands[i]; } GMEQBands& operator=(const GMEQBands& src){ for (FXint i=0;i<10;i++) bands[i]=src.bands[i]; return *this; } FXbool operator==(const GMEQBands& v) const { for (FXint i=0;i<10;i++) if (v.bands[i]!=bands[i]) return false; return true; } FXbool operator!=(const GMEQBands& v) const { for (FXint i=0;i<10;i++) if (v.bands[i]!=bands[i]) return true; return false; } void unparse(FXString & preset) const; void parse(const FXString & preset) ; }; class GMEqualizer{ public: GMEQBands bands; FXdouble preamp; FXbool enabled; public: GMEqualizer(); GMEqualizer(const GMEQBands&); FXint to_xine(FXint i) const { /// Adapted from Amarok, kaffeine, xfmedia. /// Transform (-100 ... 100) -> (1 ... 200) /// The original code was without the ceilf which returned 0 for -100. /// return (FXint)ceilf(100.0f+((float)bands[i]*0.995f)); /// I think we can go beyond the 200 limit.... return (FXint)(pow(10.0,bands[i]/20.0)*100.0); } FXint to_xine_preamp() const { return (FXint)(pow(10.0,preamp/20.0)*100.0); } FXdouble preamp_scale() const { return pow(10.0,preamp/20.0); //((FXdouble)(100+preamp))/100.0; } void load(FXSettings&); void save(FXSettings&) const; }; struct GMReplayGain { FXdouble gain; FXdouble peak; GMReplayGain() : gain(NAN),peak(NAN) {} }; /// Interface to Xine class GMPlayer : public FXObject { FXDECLARE(GMPlayer) private: xine_t * xine; xine_audio_port_t * ao; xine_stream_t * so; xine_event_queue_t * queue; xine_post_t * post_volume_normalize; private: FXString mrl; FXint position; /// Position of Stream 0...65535 FXint ctime; FXint ttime; FXint hours; /// Position -> hours FXint minutes; /// Position -> minutes FXint seconds; /// Position -> seconds FXint volume; /// Volume Level FXint progress; /// load progress FXint repeat_a; FXint repeat_b; FXString msg; /// Message from Xine FXbool ignore_uimsg; FXbool debug; GMEqualizer equalizer; GMReplayGain replaygain; // FXdouble replaygain; protected: FXbool setStringValue(const FXString & entry,const FXString & value); FXbool init(); void set_preamp(); void check_xine_error(); protected: GMPlayer(); public: enum { ID_VOLUME, ID_MUTE, ID_UNMUTE, ID_TOGGLE_MUTE, ID_PREAMP, ID_EQ_30HZ, ID_EQ_60HZ, ID_EQ_125HZ, ID_EQ_250HZ, ID_EQ_500HZ, ID_EQ_1000HZ, ID_EQ_2000HZ, ID_EQ_4000HZ, ID_EQ_8000HZ, ID_EQ_16000HZ, }; public: long onCmdVolume(FXObject*,FXSelector,void*); long onUpdVolume(FXObject*,FXSelector,void*); long onCmdMute(FXObject*,FXSelector,void*); long onUpdMute(FXObject*,FXSelector,void*); long onCmdUnMute(FXObject*,FXSelector,void*); long onUpdUnMute(FXObject*,FXSelector,void*); long onCmdToggleMute(FXObject*,FXSelector,void*); long onUpdToggleMute(FXObject*,FXSelector,void*); long onCmdEqualizer(FXObject*,FXSelector,void*); long onUpdEqualizer(FXObject*,FXSelector,void*); long onCmdPreamp(FXObject*,FXSelector,void*); long onUpdPreamp(FXObject*,FXSelector,void*); public: GMPlayer(int argc,char** argv); FXbool initialize(); FXbool opened() const; /// Open a new stream FXbool open(const FXString & mrl); /// Play the current stream from position FXbool play(FXint pos=0); FXbool seekable() const; void setRepeatAB(); FXuint getRepeatAB() const; /// Close the current stream void close(); void close_device(); FXbool changeDriver(const FXString & driver); void getAvailableDrivers(FXString & drivers); void getCurrentDriver(FXString & driver); /// Stop the current stream void stop(); /// Pause the current stream void pause(); /// Continue playback void unpause(); /// Are we currently pausing? FXbool pausing(); /// Set the playback speed void setSpeed(FXint level); /// Get the playback speed FXint getSpeed() const; void incSpeed(); void decSpeed(); FXint remaining() const; /// Are we currently playing FXbool playing() const; /// Get the current position FXint getHours() const {return hours;} FXint getMinutes() const {return minutes;} FXint getSeconds() const {return seconds;} FXint getPosition() const {return position;} FXint getPositionMS() const { return ctime; } /// Set Audio Volume (0...100) void setVolume(FXint level); /// Get Audio Volume (0...100) FXint getVolume() const; /// Mute the Audio void mute(); /// Unmute the Audiu void unmute(); /// mute or not FXbool isMute() const; FXbool checkInitialized(); FXbool hasVolumeNormalization() const; FXbool hasGapless() const; void setupGapless(); void setVolumeNormalization(FXbool enable); FXbool getVolumeNormalization() { return post_volume_normalize!=NULL; } const char * getVersion() const; /// Update the player state. void handle_async_events(); void getTrackInformation(GMTrack &); void getErrorMessage(FXString & errormsg); void disableEqualizer(); void setEqualizer(const GMEqualizer &); void getEqualizer(GMEqualizer&); void setReplayGain(FXdouble gain,FXdouble peak); ~GMPlayer(); }; #endif gogglesmm-0.12.7/src/ap_xml_parser.cpp0000644000175000001440000000333211667277404016453 0ustar sxjusers#include "gmdefs.h" #include "ap_xml_parser.h" #include namespace ap { XMLStream::XMLStream() : parser(NULL), depth(1),skip(0) { parser = XML_ParserCreate(NULL); XML_SetUserData((XML_Parser)parser,this); XML_SetElementHandler((XML_Parser)parser,xml_element_start,xml_element_end); XML_SetCharacterDataHandler((XML_Parser)parser,xml_element_data); } XMLStream::~XMLStream() { XML_ParserFree((XML_Parser)parser); } void XMLStream::xml_print_error() { fxmessage("Parse Error (line %ld, column %ld): %s\n",XML_GetCurrentLineNumber((XML_Parser)parser),XML_GetCurrentColumnNumber((XML_Parser)parser),XML_ErrorString(XML_GetErrorCode((XML_Parser)parser))); } FXbool XMLStream::parse(const FXchar * buffer,FXint length) { XML_Status code = XML_Parse((XML_Parser)parser,buffer,length,1); if (code==XML_STATUS_ERROR) { xml_print_error(); return false; } return true; } FXbool XMLStream::parse(const FXString & buffer) { return parse(buffer.text(),buffer.length()); } void XMLStream::xml_element_start(void*ptr,const FXchar * element,const FXchar ** attributes) { XMLStream * stream = reinterpret_cast(ptr); if (!stream->skip) { if (!stream->begin(element,attributes)) { stream->skip=stream->depth; } } stream->depth++; } void XMLStream::xml_element_end(void*ptr,const FXchar * element) { XMLStream * stream = reinterpret_cast(ptr); if (!stream->skip) stream->end(element); stream->depth--; // turn off skip if (stream->skip==stream->depth) stream->skip=0; } void XMLStream::xml_element_data(void*ptr,const FXchar * data,FXint len) { XMLStream * stream = reinterpret_cast(ptr); stream->data(data,len); } } gogglesmm-0.12.7/src/GMPlayListSource.h0000644000175000001440000000734711525430601016423 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMPLAYLISTSOURCE_H #define GMPLAYLISTSOURCE_H class GMPlayListSource : public GMDatabaseSource { FXDECLARE(GMPlayListSource) protected: FXint playlist; FXint current_queue; protected: GMPlayListSource(); private: GMPlayListSource(const GMPlayListSource&); GMPlayListSource& operator=(const GMPlayListSource&); protected: virtual FXint getPlayList() const { return playlist; } void getSelectedTrackQueues(FXIntList & q); void getTrackQueues(FXIntList & q); public: enum { ID_EDIT_NAME = GMDatabaseSource::ID_LAST, ID_REMOVE, ID_IMPORT, ID_LAST }; public: long onCmdEditName(FXObject*,FXSelector,void*); long onCmdRemove(FXObject*,FXSelector,void*); long onCmdRemoveInPlaylist(FXObject*,FXSelector,void*); long onCmdPaste(FXObject*,FXSelector,void*); long onCmdDrop(FXObject*,FXSelector,void*); long onCmdImport(FXObject*,FXSelector,void*); public: GMPlayListSource(GMTrackDatabase * db,FXint playlist); virtual void orderChanged(GMTrackList*) const; virtual FXbool hasCurrentTrack(GMSource * ) const; virtual FXbool findCurrent(GMTrackList * tracklist,GMSource * src); virtual void resetCurrent() { current_track=-1; current_queue=-1; } virtual void markCurrent(GMTrackList * tracklist,FXint item); virtual FXbool moveTrack(GMTrackList *,FXint from,FXint to); virtual FXString getName() const; virtual FXint getType() const { return SOURCE_DATABASE_PLAYLIST; } virtual FXint getSortColumn(FXbool browse) const { if (browse) return HEADER_BROWSE; else return HEADER_QUEUE; } virtual FXbool getQueueColumn(FXbool browse) const { if (browse) return false; else return true; } virtual FXbool defaultBrowse() const { return false; } #if FOXVERSION >= FXVERSION(1,7,12) virtual FXString settingKey() const { return "database_playlist_" + FXString::value(playlist); } #else virtual FXString settingKey() const { return "database_playlist_" + FXStringVal(playlist); } #endif virtual FXbool source_context_menu(FXMenuPane * pane); virtual FXbool genre_context_menu(FXMenuPane * pane); virtual FXbool artist_context_menu(FXMenuPane * pane); virtual FXbool album_context_menu(FXMenuPane * pane); virtual FXbool track_context_menu(FXMenuPane * pane); virtual FXbool dnd_source_accepts(FXDragType*,FXuint); virtual ~GMPlayListSource(); }; #endif gogglesmm-0.12.7/src/mpris_player.xml0000644000175000001440000000255211435112736016333 0ustar sxjusers gogglesmm-0.12.7/src/GMImageView.h0000644000175000001440000000424611525430601015351 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMIMAGEVIEW_H #define GMIMAGEVIEW_H class GMImageView : public FXGLCanvas { FXDECLARE(GMImageView) protected: FXint image_width; FXint image_height; FXuint texture_id; FXint texture_width; FXint texture_height; FXbool texture_power_of_two; protected: void updateTexture(FXImage*); public: long onPaint(FXObject*,FXSelector,void*); protected: GMImageView(); private: GMImageView(const GMImageView&); GMImageView &operator=(const GMImageView&); public: GMImageView(FXComposite* p,FXGLVisual *vis,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); virtual FXint getDefaultWidth() const; virtual FXint getDefaultHeight() const; void setImage(FXImage * img); ~GMImageView(); }; #endif gogglesmm-0.12.7/src/gmutils.cpp0000644000175000001440000004111412001272066015261 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMApp.h" #include "FXPNGImage.h" #include "FXBMPImage.h" #include "FXJPGImage.h" #include "FXGIFImage.h" #include #include #include #include #include #include #include /******************************************************************************/ #include "ap_xml_parser.h" #include using namespace ap; class XSPFParser : public XMLStream{ public: FXStringList files; FXString title; protected: FXint elem; protected: FXint begin(const FXchar *,const FXchar**); void data(const FXchar *,FXint len); void end(const FXchar *); public: enum { Elem_None, Elem_Playlist, Elem_Playlist_Title, Elem_Playlist_TrackList, Elem_Playlist_TrackList_Track, Elem_Playlist_TrackList_Track_Location, }; public: XSPFParser(); ~XSPFParser(); }; XSPFParser::XSPFParser() : elem(Elem_None) { } XSPFParser::~XSPFParser(){ } FXint XSPFParser::begin(const FXchar * element,const FXchar **/* attributes*/){ switch(elem) { case Elem_None: { if (compare(element,"playlist")==0) { elem=Elem_Playlist; return 1; } } break; case Elem_Playlist: { if (compare(element,"title")==0) { elem=Elem_Playlist_Title; return 1; } else if (compare(element,"trackList")==0) { elem=Elem_Playlist_TrackList; return 1; } } break; case Elem_Playlist_TrackList: { if (compare(element,"track")==0) { elem=Elem_Playlist_TrackList_Track; return 1; } } break; case Elem_Playlist_TrackList_Track: { if (compare(element,"location")==0) { elem=Elem_Playlist_TrackList_Track_Location; return 1; } } break; default: return 0; // skip } return 0; } void XSPFParser::data(const FXchar* str,FXint len){ if (elem==Elem_Playlist_Title) { title.assign(str,len); } else if (elem==Elem_Playlist_TrackList_Track_Location) { FXString url(str,len); files.append(url); } } void XSPFParser::end(const FXchar*) { switch(elem){ case Elem_Playlist_TrackList_Track_Location: elem=Elem_Playlist_TrackList_Track; break; case Elem_Playlist_TrackList_Track : elem=Elem_Playlist_TrackList; break; case Elem_Playlist_TrackList : case Elem_Playlist_Title : elem=Elem_Playlist; break; case Elem_Playlist : elem=Elem_None; break; } } void gm_parse_xspf(const FXString & data,FXStringList & mrl,FXString & title) { XSPFParser xspf; if (xspf.parse(data)) { mrl=xspf.files; title=xspf.title; } } /******************************************************************************/ #define URL_UNSAFE "#$-_.+!*'><()\\,%\"" // Always Encode #define URL_RESERVED ";/?:@=&" // Only encode if not used as reserved by scheme // Encode url string FXString gm_url_encode(const FXString& url){ register FXint p=0; register FXint c; FXString result; while(p='{') || strchr(URL_UNSAFE URL_RESERVED,c))){ if (!Ascii::isAlphaNumeric(c)){ result.append('%'); #if FOXVERSION < FXVERSION(1,7,0) result.append(FXString::HEX[(c>>4)&15]); result.append(FXString::HEX[c&15]); #else result.append(FXString::value2Digit[(c>>4)&15]); result.append(FXString::value2Digit[c&15]); #endif continue; } result.append(c); } return result; } FXString gm_make_url(const FXString & in) { if (in[0]=='/') return GMURL::fileToURL(in); else return in; } FXdouble gm_parse_number(const FXString & str) { if (str.empty()) return NAN; /// FOX 1.7 has its own scanf and always uses C locale for number conversions. #if FOXVERSION > FXVERSION(1,7,0) FXdouble value=NAN; if (str.scan("%lg",&value)==1) return value; else return NAN; #else errno=0; FXfloat value = strtod(str.text(),NULL); if (errno) return NAN; return value; #endif } FXbool gm_buffer_file(const FXString & filename,FXString & buffer) { FXFile file(filename,FXIO::Reading); if (file.isOpen()) { buffer.assign('\0',file.size()); return (file.readBlock((void*)buffer.text(),buffer.length())==buffer.length()); } return false; } void gm_parse_m3u(FXString & data,FXStringList & mrl) { FXint start=0,end=0,next; for (FXint i=0;istart && Ascii::isSpace(data[end])) end--; /// Parse the actual line. if ((end-start)) { if (data[start]!='#') { mrl.append(data.mid(start,1+end-start)); } } start=next; } } } void gm_parse_pls(FXString & data,FXStringList & mrl) { FXint start=0,end=0,pos,next; for (FXint i=0;istart && Ascii::isSpace(data[end])) end--; /// Parse the actual line. if ((end-start)>6) { if (compare(&data[start],"File",4)==0) { pos = data.find('=',start+4); if (pos==-1) continue; pos++; if (end-pos>0) { mrl.append(data.mid(pos,1+end-pos)); } } } start=next; } } } FXbool gm_has_opengl() { #if FOXVERSION < FXVERSION(1,7,15) int glminor,glmajor; return FXGLVisual::supported(GMApp::instance(),glmajor,glminor); #else return FXGLVisual::hasOpenGL(GMApp::instance()); #endif } void gm_focus_and_select(FXTextField * textfield) { FXASSERT(textfield->id()); textfield->setFocus(); if (!textfield->getText().empty()) textfield->setSelection(0,textfield->getText().length()); } void gm_run_popup_menu(FXMenuPane*pane,FXint rx,FXint ry) { pane->create(); pane->forceRefresh(); pane->show(); pane->grabKeyboard(); pane->popup(NULL,rx,ry); FXApp::instance()->runPopup(pane); pane->ungrabKeyboard(); } void gm_set_window_cursor(FXWindow * window,FXCursor * cur) { window->setDefaultCursor(cur); window->setDragCursor(cur); FXWindow * child=window->getFirst(); while(child) { child->setDefaultCursor(cur); child->setDragCursor(cur); child=child->getNext(); } } FXbool gm_is_local_file(const FXString & filename) { if (filename[0]=='/') return true; FXString scheme = GMURL::scheme(filename); if (scheme.empty() || (comparecase(scheme,"file")==0)) return true; else return false; } FXString gm_parse_uri(const FXString & in) { #ifndef WIN32 FXString out=in; // non-absolute path or some url if(out[0]!='/') { FXString scheme = GMURL::scheme(out); if (comparecase(scheme,"file")==0){ out = GMURL::fileFromURL(out); } else if (!scheme.empty()) { return out; } } /// Make sure we have an absolute path if (!FXPath::isAbsolute(out)) out=FXPath::absolute(out); return out; #else #error "not yet implemented" #endif } void gm_convert_filenames_to_uri(const FXStringList & filenames,FXString & uri){ if (filenames.no()) { uri=GMURL::fileToURL(filenames[0]); for (FXint i=1;i= 3) { close(i); } execlp("/bin/sh", "sh", "-c",exec.text(),(char *)0); exit(EXIT_FAILURE); } else { /// Parent Process return true; } return true; } FXbool gm_open_browser(const FXString & url) { static const char * const programs[]={"xdg-open","chromium","firefox","konqueror","opera","netscape",NULL}; return gm_launch_program(programs,url); } FXbool gm_open_folder(const FXString & folder) { static const char * const programs[]={"xdg-open","thunar","dolphin","konqueror","nautilus",NULL}; return gm_launch_program(programs,folder); } /******************************************************************************/ FXImage * gm_load_image_from_data(const void * data,FXuval size,const FXString & mime,FXint scale) { FXImage * image = NULL; // GM_DEBUG_PRINT("%s: loading image with mimetype \"%s\"\n",__func__,mime.text()); if ((comparecase(mime,"image/jpg")==0) || (comparecase(mime,"image/jpeg")==0) || (comparecase(mime,"JPG")==0)) { image=new FXJPGImage(FXApp::instance()); } else if (comparecase(mime,FXPNGImage::mimeType)==0) { image=new FXPNGImage(FXApp::instance()); } else if ((comparecase(mime,"image/bmp")==0) || (comparecase(mime,"image/x-bmp")==0) ) { image=new FXBMPImage(FXApp::instance()); } else if ((comparecase(mime,FXGIFImage::mimeType)==0)) { image=new FXGIFImage(FXApp::instance()); } else { GM_DEBUG_PRINT("%s: Mimetype \"%s\" not handled\n",__func__,mime.text()); } if (image) { FXMemoryStream store; #if FOXVERSION < FXVERSION(1,7,18) store.open(FXStreamLoad,size,(FXuchar*)data); #else store.open(FXStreamLoad,(FXuchar*)data,size); #endif if (image->loadPixels(store)) { if (scale) { if ((image->getWidth()>scale) || (image->getHeight()>scale)) { if (image->getWidth()>image->getHeight()) image->scale(scale,(scale*image->getHeight())/image->getWidth(),1); else image->scale((scale*image->getWidth())/image->getHeight(),scale,1); } } store.close(); return image; } store.close(); delete image; } return NULL; } FXbool gm_make_path(const FXString & path,FXuint perm) { #if FOXVERSION < FXVERSION(1,7,0) if(!path.empty()){ if(FXStat::isDirectory(path)) return true; if(gm_make_path(FXPath::upLevel(path),perm)){ if(FXDir::create(path,perm)) return true; } } return false; #else return FXDir::createDirectories(path,perm); #endif } FXbool gm_decode_base64(FXuchar * buffer,FXint & len){ static const FXuchar base64[256]={ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x3e,0x80,0x80,0x80,0x3f, 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x80,0x80,0x80,0x80,0x80, 0x80,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}; FXuint pos=0; FXuchar v; for (FXint i=0,b=0;i>4); buffer[pos]=(v<<4); b++; break; case 2: buffer[pos++]|=(v>>2); buffer[pos]=(v<<6); b++; break; case 3: buffer[pos++]|=v; b=0; break; } } else { if (buffer[i]=='=' && b>1) { len=pos; return true; } else { return false; } } } len=pos; return true; } void gm_colorize_bitmap(FXImage * icon,FXColor nc) { FXColor color; for (FXint y=0;ygetHeight();y++){ for (FXint x=0;xgetWidth();x++){ color=icon->getPixel(x,y); if (FXALPHAVAL(color)>0) { icon->setPixel(x,y,FXRGBA(FXREDVAL(nc),FXGREENVAL(nc),FXBLUEVAL(nc),FXALPHAVAL(color))); } } } } void gm_bgra_to_rgba(FXColor * inbuf,FXColor * outbuf, FXint len) { FXuchar * in = reinterpret_cast(inbuf); FXuchar * out = reinterpret_cast(outbuf); for (FXint i=0;i<(len*4);i+=4) { out[i+0]=in[i+2]; // r out[i+1]=in[i+1]; // g out[i+2]=in[i+0]; // b out[i+3]=in[i+3]; // a } } gogglesmm-0.12.7/src/GMQuery.h0000644000175000001440000001127311525430601014577 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMQUERY_H #define GMQUERY_H class FXCompileException : public FXErrorException { private: static const FXchar exceptionName[]; public: FXCompileException():FXErrorException(FXCompileException::exceptionName){} FXCompileException(const FXchar *msg):FXErrorException(msg){} }; class FXExecuteException : public FXErrorException { private: static const FXchar exceptionName[]; public: FXExecuteException():FXErrorException(FXExecuteException::exceptionName){} FXExecuteException(const FXchar *msg):FXErrorException(msg){} }; class FXQueryException : public FXErrorException { private: static const FXchar exceptionName[]; public: FXQueryException():FXErrorException(FXQueryException::exceptionName){} FXQueryException(const FXchar *msg):FXErrorException(msg){} }; enum FXFieldType { TYPE_INTEGER=0, TYPE_FLOAT, TYPE_TEXT, TYPE_BLOB, TYPE_NULL, }; class GMDatabase; class GMQuery{ private: GMDatabaseStatement * statement; public: /// Create a empty query GMQuery(); /// Create and compile a query. Throws FXCompileException if query couldn't be compiled GMQuery(GMDatabase * database,const FXString & query); /// Create a query. Delete Old Query. Throws FXCompileException if query couldn't be compiled void compile(GMDatabase & database,const FXString & query); /// Create a query. Delete Old Query. Throws FXCompileException if query couldn't be compiled void compile(GMDatabase * database,const FXString & query); /// Set Integer Parameter void setParameter(FXint p,FXint v); /// Set Integer Parameter void setParameter(FXint p,FXuint v); /// Set Double Parameter void setParameter(FXint p,FXfloat v); /// Set Double Parameter void setParameter(FXint p,FXdouble v); /// Set Long Parameter void setParameter(FXint p,FXlong v); /// Set String Parameter void setParameter(FXint p,const FXString & text); /// Get Num Parameters in Query FXint getNumParameters(); /// Get Index for given parameter. Returns -1 if not found FXint getParameterIndex(const FXString & name); /// Get Name of Parameter FXString getParameterName(FXint p); /// Return number of fields the query returns FXint getNumFields() const; /// Returns num columns of data returned by query. FXint getNumData() const; /// Return the specified column name the query returned. FXString getFieldName(FXint i); /// Return the column type for the specified column FXFieldType getFieldType(FXint i); /// Get Text for Column void getResult(FXint column,FXString & v); /// Get Integer for Column void getResult(FXint column,FXint & v); /// Get Integer for Column void getResult(FXint column,FXuint & v); /// Get Double for Column void getResult(FXint column,FXdouble & v); /// Get Float for Column void getResult(FXint column,FXfloat & v); /// Get Bool for Column void getResult(FXint column,FXbool & v); /// Get Long for Column void getResult(FXint column,FXlong & v); const FXchar * getResult(FXint column); /// Execute Query. Returns TRUE if there are any results, FALSE when done and throws a FXExecuteException if there is an error. FXbool execute(); FXbool perform(); /// Reset the Query void reset(); /// Clear the Query void clear(); /// Destructor ~GMQuery(); }; #endif gogglesmm-0.12.7/src/GMFetch.h0000644000175000001440000000370611525430601014525 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMFETCH_H #define GMFETCH_H struct GMFetchResponse { FXString url; FXString data; FXString content_type; }; class GMFetch : public FXThread { protected: static GMFetch * fetch; public: FXMessageChannel gui; FXStringList mrl; FXString url; FXString errormsg; protected: FXint run(); protected: GMFetch(); public: static void download(const FXString & url); static void init(); static void cancel_and_wait(); static FXbool busy(); static void exit(); }; #endif gogglesmm-0.12.7/src/GMClipboard.cpp0000644000175000001440000001014111525430601015715 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMClipboard.h" FXDEFMAP(GMClipboard) GMClipboardMap[]={ FXMAPFUNC(SEL_CLIPBOARD_LOST,0,GMClipboard::onClipboardLost), FXMAPFUNC(SEL_CLIPBOARD_GAINED,0,GMClipboard::onClipboardGained), FXMAPFUNC(SEL_CLIPBOARD_REQUEST,0,GMClipboard::onClipboardRequest), }; FXIMPLEMENT(GMClipboard,FXShell,GMClipboardMap,ARRAYNUMBER(GMClipboardMap)) GMClipboard * GMClipboard::me=NULL; FXDragType GMClipboard::kdeclipboard=0; FXDragType GMClipboard::gnomeclipboard=0; FXDragType GMClipboard::gnomedragndrop=0; FXDragType GMClipboard::trackdatabase=0; FXDragType GMClipboard::selectedtracks=0; FXDragType GMClipboard::alltracks=0; GMClipboard * GMClipboard::instance(){ return me; } GMClipboard::GMClipboard() { } GMClipboard::GMClipboard(FXApp * app) : FXShell(app,0,0,0,0,0), clipdata(NULL), clipowner(NULL) { me=this; } void GMClipboard::create(){ FXShell::create(); kdeclipboard = getApp()->registerDragType("application/x-kde-cutselection"); gnomeclipboard = getApp()->registerDragType("x-special/gnome-copied-files"); gnomedragndrop = getApp()->registerDragType("x-special/gnome-icon-list"); trackdatabase = getApp()->registerDragType("application/goggles-music-manager-database"); selectedtracks = getApp()->registerDragType("application/goggles-dnd-selected-tracks"); alltracks = getApp()->registerDragType("application/goggles-dnd-all-tracks"); if (FXWindow::urilistType==0){ FXWindow::urilistType=getApp()->registerDragType(FXWindow::urilistTypeName); } } GMClipboard::~GMClipboard(){ if (clipdata) delete clipdata; clipowner=NULL; } bool GMClipboard::doesOverrideRedirect() const { return true; } FXbool GMClipboard::acquire(FXObject * owner,const FXDragType * types,FXuint num_types,GMClipboardData * data){ if (acquireClipboard(types,num_types)){ // fxmessage("acquired clipboard %d\n",hasClipboard()); clipowner=owner; clipdata=data; return true; } return false; } FXbool GMClipboard::owned(FXObject * obj){ if (hasClipboard() && obj==clipowner) return true; return false; } FXbool GMClipboard::release(){ return false; } long GMClipboard::onClipboardLost(FXObject*,FXSelector,void*){ // fxmessage("lost clipboard\n"); if (clipdata) delete clipdata; clipowner=NULL; return 1; } long GMClipboard::onClipboardGained(FXObject*,FXSelector,void*){ // fxmessage("gained clipboard\n"); return 1; } long GMClipboard::onClipboardRequest(FXObject*,FXSelector,void*ptr){ FXEvent *event=(FXEvent*)ptr; // fxmessage("got request: %s\n",getApp()->getDragTypeName(event->target).text()); if (clipdata && clipdata->request(event->target,this)){ return 1; } return 0; } gogglesmm-0.12.7/src/GMAudioScrobbler.h0000644000175000001440000001160512063215564016377 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2008-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMAUDIOSCROBBLER_H #define GMAUDIOSCROBBLER_H struct GMAudioScrobblerTrack { FXString artist; FXString album; FXString title; FXuint duration; FXint no; FXlong timestamp; FXint loveban; GMAudioScrobblerTrack(){} GMAudioScrobblerTrack(FXlong time,GMTrack & t,FXint lb) : artist(t.artist),album(t.album),title(t.title),duration(t.time),no(t.no),timestamp(time)/* LastFM */,loveban(lb)/* LastFM End */{} void load(FXStream & store); void save(FXStream & store) const; FXuint getTimeStamp() const { return (FXuint)(timestamp/1000000000); } void clear(); }; typedef FXArray GMAudioScrobblerTrackList; enum { SERVICE_LASTFM, SERVICE_LIBREFM, SERVICE_CUSTOM }; class GMAudioScrobbler : public FXThread { private: FXMutex mutex_task; FXMutex mutex_data; FXCondition condition_task; FXuchar flags; FXMessageChannel feedback; FXObject* target; FXSelector message; FXbool started; private: FXuint mode; FXString handshake_url; FXString nowplaying_url; FXString submit_url; FXString username; FXString password; FXString session; FXString token; protected: FXlong timeout; private: enum { TASK_NONE = 0x0, TASK_LOGIN = 0x1, TASK_NOWPLAYING = 0x2, TASK_SUBMIT = 0x4, TASK_SHUTDOWN = 0x8, TASK_AUTHENTICATE = 0x10, }; private: enum { FLAG_NONE = 0, FLAG_LOGIN_CHANGED = 0x1, FLAG_BANNED = 0x2, FLAG_BADAUTH = 0x4, FLAG_BADTIME = 0x8, FLAG_SHUTDOWN = 0x10, FLAG_TIMEOUT = 0x20, FLAG_NETWORK = 0x40, FLAG_DISABLED = 0x80, FLAG_SERVICE = 0x100 }; protected: FXint run(); protected: FXbool post_request(const FXString & url,const FXString & request,FXString & response); FXbool get_request(const FXString & url,FXString & response); protected: FXuchar getNextTask(); FXbool waitForTask(); void runTask(); void wakeup(); protected: GMAudioScrobblerTrack nowplayingtrack; GMAudioScrobblerTrackList submitqueue; FXint nsubmitted; FXint nfailed; protected: void authenticate(); void handshake(); void submit(); void nowplaying(); void loveban(); void create_loveban_request(FXString &); void process_loveban_response(const FXString&); void create_token_request(FXString &); void process_token_response(const FXString&); FXuint create_handshake_request(FXString &); void process_handshake_response(const FXString&); void create_nowplaying_request(FXString &); void process_nowplaying_response(const FXString&); void create_submit_request(FXString &); void process_submit_response(const FXString&); void set_timeout(); void reset_timeout(); void set_submit_failed(); void load_queue(); void save_queue(); FXbool can_submit(); public: GMAudioScrobbler(FXObject* tgt,FXSelector msg); FXString getUsername(); FXbool hasPassword(); FXbool isBanned(); FXbool isEnabled(); FXuint getService(); void nowplaying(GMTrack & info); void loveban(GMTrack & info, FXint loveban); void service(FXuint s); void submit(FXlong timestamp,GMTrack & info); void login(const FXString & user,const FXString & pass); void shutdown(); void nudge(); void disable(); void enable(); virtual ~GMAudioScrobbler(); }; extern FXbool init_gcrypt(); #endif gogglesmm-0.12.7/src/GMDatabaseSource.cpp0000644000175000001440000025401111573755012016722 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMList.h" #include "GMDatabase.h" #include "GMTrackDatabase.h" #include "GMTrackList.h" #include "GMTrackItem.h" #include "GMTrackView.h" #include "GMWindow.h" #include "GMSource.h" #include "GMSourceView.h" #include "GMClipboard.h" #include "GMDatabaseSource.h" #include "GMPlayListSource.h" #include "GMPlayerManager.h" #include "GMTag.h" #include "GMIconTheme.h" #include "GMFilename.h" #include "GMThread.h" #include "GMSearch.h" #include "GMAudioScrobbler.h" #include "GMImportDialog.h" #include #include "icons.h" static void updateTrackFilenames(GMTrackDatabase * db,FXIntList & tracks) { register FXint i=0; FXint numchanges=0; FXString mrl; GMTrack trackinfo; FXStringList newmrls; FXStringList oldmrls; if (!GMPlayerManager::instance()->getPreferences().export_format_template.contains("%T")) { FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Invalid Template"),fxtr("The provided template is invalid. The track title %%T needs to be specified.\nPlease fix the filename template in the preference panel.")); return; } FXTextCodec * codec = GMFilename::findcodec(GMPlayerManager::instance()->getPreferences().export_encoding); FXuint options=0; if (GMPlayerManager::instance()->getPreferences().export_lowercase) options|=GMFilename::LOWERCASE; if (GMPlayerManager::instance()->getPreferences().export_lowercase_extension) options|=GMFilename::LOWERCASE_EXTENSION; if (GMPlayerManager::instance()->getPreferences().export_underscore) options|=GMFilename::NOSPACES; /// Create New Mrls. for (i=0;igetTrack(tracks[i],trackinfo)) { FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Database Error"),fxtr("Oops. Database Error")); return; } if (GMFilename::create(mrl,trackinfo,GMPlayerManager::instance()->getPreferences().export_format_template,GMPlayerManager::instance()->getPreferences().export_character_filter,options,codec) && mrl!=trackinfo.mrl) { newmrls.append(mrl); oldmrls.append(trackinfo.mrl); numchanges++; } else { newmrls.append(FXString::null); oldmrls.append(FXString::null); } } if (numchanges==0){ FXMessageBox::information(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("No changes"),fxtr("Filenames did not require any changes")); delete codec; return; } /// Ask For Permission FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Rename Audio Files?"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,600,400,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Renaming Audio Files…"),fxtr("The following audio files are going to be renamed")); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Rename"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y); GMScrollFrame * sunken = new GMScrollFrame(main); GMList * list = new GMList(sunken,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); for (i=0;iappendItem(newmrls[i]); } } if (dialog.execute()) { for (i=0;isetTrackFilename(tracks[i],newmrls[i]); } else { if (i+1getMainWindow(),MBOX_YES_NO,fxtr("Unable to rename file"),fxtrformat("Unable to rename:\n%s\n\nto:%s\nContinue renaming files?"),oldmrls[i].text(),newmrls[i].text())==MBOX_CLICKED_NO) break; } else { FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Unable to rename file"),fxtrformat("Unable to rename:\n%s\n\nto:%s"),oldmrls[i].text(),newmrls[i].text()); } } } } } } } delete codec; } class GMFilenameTemplateDialog : public FXDialogBox { FXDECLARE(GMFilenameTemplateDialog) protected: FXFontPtr font_fixed; FXDataTarget target_format_template; FXDataTarget target_export_lowercase; FXDataTarget target_export_lowercase_extension; FXDataTarget target_export_underscore; FXDataTarget target_export_encoding; FXDataTarget target_export_filter; protected: GMFilenameTemplateDialog(){} private: GMFilenameTemplateDialog(const GMFilenameTemplateDialog&); GMFilenameTemplateDialog &operator=(const GMFilenameTemplateDialog&); public: GMFilenameTemplateDialog(FXWindow*); ~GMFilenameTemplateDialog(); }; FXIMPLEMENT(GMFilenameTemplateDialog,FXDialogBox,0,0); GMFilenameTemplateDialog::GMFilenameTemplateDialog(FXWindow*p) : FXDialogBox(p,FXString::null,DECOR_TITLE|DECOR_BORDER,0,0,0,0,0,0,0,0,0,0) { setTitle(tr("Filename Template")); const FXuint labelstyle=LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT; target_format_template.connect(GMPlayerManager::instance()->getPreferences().export_format_template); target_export_lowercase.connect(GMPlayerManager::instance()->getPreferences().export_lowercase); target_export_lowercase_extension.connect(GMPlayerManager::instance()->getPreferences().export_lowercase_extension); target_export_underscore.connect(GMPlayerManager::instance()->getPreferences().export_underscore); target_export_encoding.connect(GMPlayerManager::instance()->getPreferences().export_encoding); target_export_filter.connect(GMPlayerManager::instance()->getPreferences().export_character_filter); /// Create a fixed font, about the same size as the normal font FXint size = FXApp::instance()->getNormalFont()->getSize(); font_fixed = new FXFont(FXApp::instance(),"mono",(int)size/10,FXFont::Normal,FXFont::Straight,FONTENCODING_UNICODE,FXFont::NonExpanded,FXFont::Modern|FXFont::Fixed); FXVerticalFrame * main=new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y); new FXLabel(main,tr("Template may contain absolute or relative path, environment variables\nand ~. Relative paths are based on the location of the original file. The\nfile extension gets automatically added. The following macros\nmay be used:"),NULL,JUSTIFY_LEFT); FXLabel * label = new FXLabel(main,tr("%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n%G - genre" ),NULL,JUSTIFY_LEFT,0,0,0,0,30); label->setFont(font_fixed); new FXLabel(main,tr("Conditions may be used as well:"),NULL,JUSTIFY_LEFT); label = new FXLabel(main,tr("?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" ),NULL,JUSTIFY_LEFT,0,0,0,0,30); label->setFont(font_fixed); new FXSeparator(main,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXMatrix * matrix = new FXMatrix(main,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,0,0,4,0); new FXLabel(matrix,tr("Template:"),NULL,labelstyle); FXTextField * textfield = new GMTextField(matrix,20,&target_format_template,FXDataTarget::ID_VALUE,LAYOUT_FILL_X|TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN); textfield->setFont(font_fixed); new FXLabel(matrix,tr("Encoding:"),NULL,labelstyle); GMListBox * list_codecs = new GMListBox(matrix,&target_export_encoding,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN); for (int i=0;gmcodecnames[i]!=NULL;i++) list_codecs->appendItem(gmcodecnames[i]); list_codecs->setNumVisible(9); new FXLabel(matrix,tr("Exclude:"),NULL,labelstyle); textfield = new GMTextField(matrix,15,&target_export_filter,FXDataTarget::ID_VALUE,LAYOUT_FILL_X|TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN); textfield->setFont(font_fixed); new FXLabel(matrix,tr("Options:"),NULL,labelstyle); new GMCheckButton(matrix,tr("Replace spaces with underscores"),&target_export_underscore,FXDataTarget::ID_VALUE,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,fxtr("Lower case"),&target_export_lowercase,FXDataTarget::ID_VALUE,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,fxtr("Lower case extension"),&target_export_lowercase_extension,FXDataTarget::ID_VALUE,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXSeparator(main,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0); new GMButton(closebox,fxtr("&Close"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); } GMFilenameTemplateDialog::~GMFilenameTemplateDialog(){ GMPlayerManager::instance()->getPreferences().export_format_template.trim(); } FXbool GMDatabaseClipboardData::request(FXDragType target,GMClipboard * clipboard){ if (target==GMClipboard::urilistType){ FXString uri; FXStringList filenames; db->getTrackFilenames(tracks,filenames); gm_convert_filenames_to_uri(filenames,uri); clipboard->setDNDData(FROM_CLIPBOARD,target,uri); return true; } else if (target==GMClipboard::kdeclipboard){ clipboard->setDNDData(FROM_CLIPBOARD,target,"0"); return true; } else if (target==GMClipboard::gnomeclipboard){ FXString clipdata; FXStringList filenames; db->getTrackFilenames(tracks,filenames); gm_convert_filenames_to_gnomeclipboard(filenames,clipdata); clipboard->setDNDData(FROM_CLIPBOARD,target,clipdata); return true; } return false; } FXDEFMAP(GMDatabaseSource) GMDatabaseSourceMap[]={ // FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EDIT_GENRE,GMDatabaseSource::onCmdEditGenre), // FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EDIT_ARTIST,GMDatabaseSource::onCmdEditArtist), // FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EDIT_ALBUM,GMDatabaseSource::onCmdEditAlbum), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EDIT_TRACK,GMDatabaseSource::onCmdEditTrack), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_DELETE_GENRE,GMDatabaseSource::onCmdDelete), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_DELETE_ARTIST,GMDatabaseSource::onCmdDelete), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_DELETE_ALBUM,GMDatabaseSource::onCmdDelete), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_DELETE_TRACK,GMDatabaseSource::onCmdDelete), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EXPORT_GENRE,GMDatabaseSource::onCmdExportTracks), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EXPORT_ARTIST,GMDatabaseSource::onCmdExportTracks), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EXPORT_ALBUM,GMDatabaseSource::onCmdExportTracks), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EXPORT_TRACK,GMDatabaseSource::onCmdExportTracks), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_COPY_ARTIST,GMDatabaseSource::onCmdCopyArtistAlbum), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_COPY_ALBUM,GMDatabaseSource::onCmdCopyArtistAlbum), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_COPY_TRACK,GMDatabaseSource::onCmdCopyTrack), FXMAPFUNC(SEL_DND_REQUEST,GMDatabaseSource::ID_COPY_ARTIST,GMDatabaseSource::onCmdRequestArtistAlbum), FXMAPFUNC(SEL_DND_REQUEST,GMDatabaseSource::ID_COPY_ALBUM,GMDatabaseSource::onCmdRequestArtistAlbum), FXMAPFUNC(SEL_DND_REQUEST,GMDatabaseSource::ID_COPY_TRACK,GMDatabaseSource::onCmdRequestTrack), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_EXPORT,GMDatabaseSource::onCmdExport), FXMAPFUNC(SEL_UPDATE,GMDatabaseSource::ID_EXPORT,GMDatabaseSource::onUpdExport), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_NEW_PLAYLIST,GMDatabaseSource::onCmdNewPlayList), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_IMPORT_PLAYLIST,GMDatabaseSource::onCmdImportPlayList), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_CLEAR,GMDatabaseSource::onCmdClear), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_INFO,GMDatabaseSource::onCmdInfo), FXMAPFUNC(SEL_DND_DROP,GMDatabaseSource::ID_DROP,GMDatabaseSource::onCmdDrop), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_PASTE,GMDatabaseSource::onCmdPaste), FXMAPFUNC(SEL_UPDATE,GMDatabaseSource::ID_PASTE,GMDatabaseSource::onUpdPaste), FXMAPFUNC(SEL_TIMEOUT,GMDatabaseSource::ID_TRACK_PLAYED,GMDatabaseSource::onCmdTrackPlayed), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_FILENAME_TEMPLATE,GMDatabaseSource::onCmdFilenameTemplate), FXMAPFUNC(SEL_COMMAND,GMDatabaseSource::ID_OPEN_FOLDER,GMDatabaseSource::onCmdOpenFolder) }; FXIMPLEMENT(GMDatabaseSource,GMSource,GMDatabaseSourceMap,ARRAYNUMBER(GMDatabaseSourceMap)); GMDatabaseSource* GMDatabaseSource::filterowner=NULL; GMDatabaseSource::GMDatabaseSource() : dbowned(true), db(NULL),filtermask(0),hasfilter(false) { sort_browse=GMDBTrackItem::browseSort; } GMDatabaseSource::GMDatabaseSource(GMTrackDatabase * database) : dbowned(true), db(database),filtermask(FILTER_DEFAULT),hasfilter(false) { FXASSERT(db); sort_browse=GMDBTrackItem::browseSort; } GMDatabaseSource::~GMDatabaseSource() { clearAlbumIconCache(); if (dbowned) delete db; } #include // need this for rand() //generates a psuedo-random integer between min and max int randint(int min, int max,unsigned int * random_seed) { return min+int( ((double)(max-min+1))*rand_r(random_seed)/(RAND_MAX+1.0)); } void GMDatabaseSource::shuffle(GMTrackList*list,FXuint sort_seed) const { list->setSortFunc(GMDBTrackItem::ascendingAlbum); list->sortItems(); list->setSortFunc(NULL); /// Initial Value comes from sort_seed (read from registry and such...) FXuint random_seed = sort_seed; rand_r(&random_seed); FXint n; FXint nitems=list->getNumItems()-1; for (FXint i=0;igetNumItems()); list->moveItem(i,n); } } void GMDatabaseSource::configure(GMColumnList& list) const { list.no(10); list[0]=GMColumn(notr("No."),HEADER_TRACK,GMDBTrackItem::ascendingTrack,GMDBTrackItem::descendingTrack,43,(getPlayList()==-1) ? true : false ,true,0); list[1]=GMColumn(notr("Queue"),HEADER_QUEUE,GMDBTrackItem::ascendingQueue,GMDBTrackItem::descendingQueue,60,(getPlayList()==-1) ? false : true,false,1); list[2]=GMColumn(notr("Title"),HEADER_TITLE,GMDBTrackItem::ascendingTitle,GMDBTrackItem::descendingTitle,360,true,true,2); list[3]=GMColumn(notr("Artist"),HEADER_ARTIST,GMDBTrackItem::ascendingArtist,GMDBTrackItem::descendingArtist,400,true,false,3); list[4]=GMColumn(notr("Album Artist"),HEADER_ALBUM_ARTIST,GMDBTrackItem::ascendingAlbumArtist,GMDBTrackItem::descendingAlbumArtist,200,true,false,4); list[5]=GMColumn(notr("Album"),HEADER_ALBUM,GMDBTrackItem::ascendingAlbum,GMDBTrackItem::descendingAlbum,200,true,false,5); list[6]=GMColumn(notr("Disc"),HEADER_DISC,GMDBTrackItem::ascendingDisc,GMDBTrackItem::descendingDisc,43,false,false,6); list[7]=GMColumn(notr("Genre"),HEADER_GENRE,GMDBTrackItem::ascendingGenre,GMDBTrackItem::descendingGenre,200,true,false,7); list[8]=GMColumn(notr("Year"),HEADER_YEAR,GMDBTrackItem::ascendingYear,GMDBTrackItem::descendingYear,60,true,true,8); list[9]=GMColumn(notr("Time"),HEADER_TIME,GMDBTrackItem::ascendingTime,GMDBTrackItem::descendingTime,60,true,true,9); } FXbool GMDatabaseSource::hasCurrentTrack(GMSource * src) const { if (src==this) return true; return false; } FXbool GMDatabaseSource::findCurrent(GMTrackList * list,GMSource * src) { GMDatabaseSource * db = dynamic_cast(src); if (db && db->getCurrentTrack()!=-1 ) return GMSource::findCurrent(list,db); return false; } FXbool GMDatabaseSource::findCurrentArtist(GMList * list,GMSource * src) { GMDatabaseSource * dbs = dynamic_cast(src); if (dbs && dbs->getCurrentTrack()!=-1 ){ FXint artist,album; db->getTrackAssociation(dbs->getCurrentTrack(),artist,album); if (artist==-1) return false; for (FXint i=0;igetNumItems();i++){ if (artist==(FXint)(FXival)list->getItemData(i)){ list->selectItem(i); list->makeItemVisible(i); return true; } } } return false; } FXbool GMDatabaseSource::findCurrentAlbum(GMList * list,GMSource * src) { GMDatabaseSource * dbs = dynamic_cast(src); if (dbs && dbs->getCurrentTrack()!=-1 ){ FXint artist=-1,album=-1,i,j; GMAlbumListItem * item=NULL; db->getTrackAssociation(dbs->getCurrentTrack(),artist,album); if (album==-1) return false; for (i=0;igetNumItems();i++){ item = dynamic_cast(list->getItem(i)); if (!item) continue; if (album==(FXint)(FXival)list->getItemData(i)){ list->selectItem(i); list->makeItemVisible(i); return true; } for (j=0;jalbums.no();j++){ if (album==item->albums[j]){ list->selectItem(i); list->makeItemVisible(i); return true; } } } } return false; } FXIcon * GMDatabaseSource::getAlbumIcon(FXint aid,FXbool cacheonly){ FXIconSource src(FXApp::instance()); GMCover * cover=NULL; FXIcon * albumicon=NULL; FXString path; albumicon = (FXIcon*)albumicons.find((void*)(FXival)aid); if (albumicon==NULL && !cacheonly && db->getAlbumTrack(aid,path)) { cover = GMCover::fromTag(path,48); if (cover==NULL) { cover = GMCover::fromPath(FXPath::directory(path),48); } if (cover) { albumicon = GMCover::toIcon(cover); albumicon->create(); albumicons.insert((void*)(FXival)aid,(void*)albumicon); } } return albumicon; } FXIcon * GMDatabaseSource::getAlbumIcon(){ return getAlbumIcon(db->getTrackAlbum(current_track),false); } FXbool GMDatabaseSource::hasTrack(const FXString & mrl,FXint & id) { return db->hasTrack(mrl,id); } void GMDatabaseSource::clearAlbumIconCache() { FXIcon * albumicon; #if FOXVERSION < FXVERSION(1,7,0) for (FXint i=0;ilistPlaylists(playlists)) { for (FXint i=0;igetNumTracks(); } FXint GMDatabaseSource::getNumStreams() const{ return db->getNumStreams(); } FXString GMDatabaseSource::getTrackFilename(FXint id) const{ return db->getTrackFilename(id); } FXbool GMDatabaseSource::getTrack(GMTrack & info) const{ return db->getTrack(current_track,info); } FXbool GMDatabaseSource::genre_context_menu(FXMenuPane * pane) { //new FXMenuCommand(pane,fxtr("Edit…\tF2\tEdit Genre."),GMIconTheme::instance()->icon_edit,this,GMDatabaseSource::ID_EDIT_GENRE); // new FXMenuCommand(pane,"Export" … "\t\tCopy associated tracks to destination.",GMIconTheme::instance()->icon_export,this,ID_EXPORT_GENRE); // new FXMenuSeparator(pane); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove Genre from Library."),GMIconTheme::instance()->icon_delete,this,GMSource::ID_DELETE_GENRE); return true; } FXbool GMDatabaseSource::artist_context_menu(FXMenuPane * pane){ //new FXMenuCommand(pane,fxtr("Edit…\tF2\tEdit Artist."),GMIconTheme::instance()->icon_edit,this,GMDatabaseSource::ID_EDIT_ARTIST); new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy associated tracks to the clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_ARTIST); // new FXMenuCommand(pane,"Export" … "\t\tCopy associated tracks to destination.",GMIconTheme::instance()->icon_export,this,ID_EXPORT_ARTIST); new FXMenuSeparator(pane); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove associated tracks from library."),GMIconTheme::instance()->icon_delete,this,GMSource::ID_DELETE_ARTIST); return true; } FXbool GMDatabaseSource::album_context_menu(FXMenuPane * pane){ //new FXMenuCommand(pane,fxtr("Edit…\tF2\tEdit Album."),GMIconTheme::instance()->icon_edit,this,GMDatabaseSource::ID_EDIT_ALBUM); new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy associated tracks to the clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_ALBUM); // new FXMenuCommand(pane,"Export" … "\t\tCopy associated tracks to destination.",GMIconTheme::instance()->icon_export,this,ID_EXPORT_ALBUM); new FXMenuSeparator(pane); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove associated tracks from library."),GMIconTheme::instance()->icon_delete,this,GMSource::ID_DELETE_ALBUM); return true; } FXbool GMDatabaseSource::track_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Edit…\tF2\tEdit Track Information."),GMIconTheme::instance()->icon_edit,this,GMDatabaseSource::ID_EDIT_TRACK); new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy track(s) to clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_TRACK); // new FXMenuCommand(pane,"Export" … "\t\tCopy tracks to destination.",GMIconTheme::instance()->icon_export,this,ID_EXPORT_TRACK); new FXMenuSeparator(pane); if (GMPlayerManager::instance()->getTrackView()->numTrackSelected()==1) new GMMenuCommand(pane,fxtr("Open Folder Location\t\tOpen Folder Location."),NULL,this,ID_OPEN_FOLDER); // if (GMPlayerManager::instance()->getTrackView()->numTrackSelected()==1) // new FXMenuCommand(pane,"Copy Folder Location\t\tCopy Folder Location to clipboard.",GMIconTheme::instance()->icon_copy,this,ID_COPY_LOCATION); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove track(s) from library."),GMIconTheme::instance()->icon_delete,this,GMSource::ID_DELETE_TRACK); /* if (getCurrentSourceType()==SOURCE_PLAYLIST && !browserframe->shown()) { new FXMenuCommand(&pane,"Remove from Playlist\t\tRemove track(s) from playlist.",icon_delete,this,ID_PLAYLIST_DEL_TRACK); new FXMenuSeparator(&pane); new FXMenuCommand(&pane,tr("Reorder Playlist"),NULL,this,ID_REORDER_PLAYLIST); } */ return true; } FXbool GMDatabaseSource::source_context_menu(FXMenuPane * pane){ // new FXMenuCommand(pane,fxtr("Import Folder…\tCtrl-O\tImport Music from folder into Library"),GMIconTheme::instance()->icon_import,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_IMPORT_DIRS); new GMMenuCommand(pane,fxtr("New Play List…\t\tCreate a new play list."),GMIconTheme::instance()->icon_playlist,this,GMDatabaseSource::ID_NEW_PLAYLIST); new FXMenuSeparator(pane); new GMMenuCommand(pane,fxtr("Export…"),GMIconTheme::instance()->icon_export,this,GMDatabaseSource::ID_EXPORT); new GMMenuCommand(pane,fxtr("Information…\t\tLibrary Statistics"),GMIconTheme::instance()->icon_info,this,GMDatabaseSource::ID_INFO); new FXMenuSeparator(pane); new GMMenuCommand(pane,fxtr("Remove All Tracks\t\tRemove all tracks from the library"),GMIconTheme::instance()->icon_delete,this,GMDatabaseSource::ID_CLEAR); return true; } FXbool GMDatabaseSource::dnd_source_accepts(FXDragType*types,FXuint ntypes){ if (FXApp::instance()->getDragWindow()) return false; for (FXuint i=0;idatabase()->execute("DROP VIEW IF EXISTS filtered;"); if (keywords.no() && filtermask) { FXString query = "CREATE TEMP VIEW filtered AS SELECT tracks.id as track ,albumartists.id as artist ,albums.id as album ,genre FROM tracks,artists AS trackartists, artists AS albumartists,albums,genres WHERE tracks.album == albums.id AND albumartists.id == albums.artist AND trackartists.id == tracks.artist AND tracks.genre == genres.id "; if (getPlayList()!=-1) { query+=" AND tracks.id IN (SELECT DISTINCT(track) FROM playlist_tracks WHERE playlist == " + GMStringVal(getPlayList()) + ") "; } for (FXint i=0;idatabase()->execute(query); #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("setFilter(): %lld\n",end-start); #endif hasfilter=true; } else { #ifdef DEBUG fxmessage("No Filter\n"); #endif hasfilter=false; } filterowner=this; return true; } FXbool GMDatabaseSource::listGenres(GMList * list,FXIcon * icon) { FXint id; const FXchar * name; GMQuery q; FXString query; #ifdef DEBUG FXlong start = fxgetticks(); #endif try { if (getPlayList()==-1) { if (!hasFilter()) { while(db->list_genres.execute()) { db->list_genres.getResult(0,id); name = db->list_genres.getResult(1); list->appendItem(name,icon,(void*)(FXival)id); } db->list_genres.reset(); #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("listGenres(): %30lld\n",end-start); #endif return true; } else { query = "SELECT genres.id,genres.name FROM genres WHERE id IN (SELECT genre FROM filtered); "; } } else { if (!hasFilter()) { query = "SELECT id,name " "FROM genres " "WHERE id IN ( " "SELECT DISTINCT(genre) " "FROM tracks,playlist_tracks " "WHERE id == playlist_tracks.track AND playlist_tracks.playlist == " + GMStringVal(getPlayList()) + ");"; } else { query = "SELECT genres.id,genres.name FROM genres WHERE id IN (SELECT genre FROM filtered); "; } } q.compile(db->database(),query); while( q.execute()){ q.getResult(0,id); name=q.getResult(1); list->appendItem(name,icon,(void*)(FXival)id); } q.reset(); } catch(FXCompileException &){ list->clearItems(); return false; } catch(FXExecuteException &){ list->clearItems(); return false; } #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("listGenres(): %30lld\n",end-start); #endif return true; } FXbool GMDatabaseSource::listArtists(GMList * list,FXIcon * icon,const FXIntList & genrelist){ GMListItem * item; const FXchar * name; FXint id; GMQuery q; FXString query; FXString filterquery; #ifdef DEBUG FXlong start = fxgetticks(); #endif try { if (!hasFilter()){ if (genrelist.no()==0) { if (getPlayList()==-1) { query = "SELECT id,name FROM artists WHERE id IN (SELECT DISTINCT(artist) FROM albums);"; } else{ query = "SELECT DISTINCT(artists.id), artists.name " "FROM artists,albums " "WHERE albums.artist == artists.id AND albums.id IN ( " "SELECT DISTINCT(album) FROM tracks WHERE id IN ( " "SELECT DISTINCT(track) FROM playlist_tracks WHERE playlist == " + GMStringVal(getPlayList()) + "));"; } } else { if (getPlayList()==-1) { if (genrelist.no()>1) { query = "SELECT id, name FROM artists " "WHERE id IN ( " "SELECT DISTINCT(artist) " "FROM albums WHERE id IN ( " "SELECT DISTINCT(album) FROM tracks "; query+=" WHERE genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query = "SELECT DISTINCT(artists.id), artists.name " "FROM artists,albums " "WHERE albums.artist == artists.id AND albums.id IN ( " "SELECT DISTINCT(album) " "FROM tracks "; query+=" WHERE genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query+=" WHERE genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;idatabase(),query); while( q.execute()){ q.getResult(0,id); name=q.getResult(1); item = new GMListItem(name,icon,(void*)(FXival)id); item->setDraggable(true); list->appendItem(item); } q.reset(); } catch(FXCompileException &){ list->clearItems(); return false; } catch(FXExecuteException &){ list->clearItems(); return false; } #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("listArtist(): %30lld\n",end-start); #endif return true; } FXbool GMDatabaseSource::listAlbums(GMList * list,FXIcon * icon,const FXIntList & artistlist,const FXIntList & genrelist){ const FXchar * c_name=NULL; FXint id; FXint year; FXString name; FXString query; FXIcon * albumicon=NULL; #ifdef DEBUG FXlong start = fxgetticks(); #endif GMAlbumListItem * item=NULL; GMQuery q; try { if (hasFilter()){ query = "SELECT albums.id,albums.name,albums.year FROM albums WHERE id IN (SELECT album FROM filtered "; if (artistlist.no()>1) { query+=" WHERE artist IN ( " + GMStringVal(artistlist[0]); for (FXint i=1;i1) { query+=" AND genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query+=" AND genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query+=" WHERE genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query+=" WHERE albums.artist IN ( " + GMStringVal(artistlist[0]); for (FXint i=1;i=0) query+=",playlist_tracks"; // if (artistlist.no() || !filter.empty()) // query+=" WHERE album_artist.album == tracks.album AND album_artist.album == albums.id"; // else query+=" WHERE albums.id == tracks.album"; if (getPlayList()>=0) { query+=" AND playlist_tracks.track == tracks.id"; query+=" AND playlist_tracks.playlist == "+GMStringVal(getPlayList()); } if (genrelist.no()) { if (genrelist.no()>1) { query+=" AND genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i1) { query+=" AND albums.artist IN ( " + GMStringVal(artistlist[0]); for (FXint i=1;idatabase(),query); while(q.execute()){ q.getResult(0,id); c_name = q.getResult(1); q.getResult(2,year); if (c_name!=NULL && item && c_name==name) { FXASSERT(item); item->albums.append(id); } else { name=c_name; if (GMPlayerManager::instance()->getPreferences().gui_show_albumcovers){ albumicon = getAlbumIcon(id,true); if (albumicon) item = new GMAlbumListItem(c_name,albumicon,id,year); else item = new GMAlbumListItem(c_name,icon,id,year); } else { item = new GMAlbumListItem(c_name,icon,id,year); } list->appendItem(item); } } } catch(FXCompileException &){ list->clearItems(); return false; } catch(FXExecuteException &){ list->clearItems(); return false; } #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("listAlbums(): %30lld\n",end-start); #endif return true; } FXbool GMDatabaseSource::listTracks(GMTrackList * tracklist,const FXIntList & albumlist,const FXIntList & genrelist){ GMQuery q; FXString query; const FXchar * c_artist; const FXchar * c_albumname; const FXchar * c_albumartist; const FXchar * c_title; const FXchar * c_genre; FXint time; FXuint no; FXint id; FXint queue=1; FXint year; FXint trackyear; GMDBTrackItem * item; GMDBTrackItem::max_queue=0; GMDBTrackItem::max_trackno=0; GMDBTrackItem::max_time=0; #ifdef DEBUG FXlong start = fxgetticks(); #endif try { if (getPlayList()>=0) { query = "SELECT tracks.id,title,time,no,tracks.year,genres.name,a1.name,a2.name,albums.name,albums.year, playlist_tracks.queue " "FROM tracks, genres, albums, artists AS a1, artists AS a2, playlist_tracks "; } else { query = "SELECT tracks.id,title,time,no,tracks.year,genres.name,a1.name,a2.name,albums.name,albums.year " "FROM tracks, genres, albums, artists AS a1, artists AS a2 "; } query += " WHERE genres.id == tracks.genre AND " "a1.id == albums.artist AND " "a2.id == tracks.artist AND " "tracks.album == albums.id"; if (genrelist.no()) { if (genrelist.no()>1) { query+=" AND genre IN ( " + GMStringVal(genrelist[0]); for (FXint i=1;i=0) { query+=" AND playlist_tracks.track == tracks.id"; if (!hasFilter()) query+=" AND playlist_tracks.playlist == "+GMStringVal(getPlayList()); } if (albumlist.no()) { if (albumlist.no()>1) { query+=" AND tracks.album IN ( "; query+=GMStringVal(albumlist[0]); for (FXint i=1;i=0) query+=" ORDER BY playlist_tracks.queue;"; else query+=";"; //fxmessage("query: %s\n",query.text()); q.compile(db->database(),query); if (getPlayList()>=0) { while(q.execute()){ q.getResult(0,id); c_title = q.getResult(1); q.getResult(2,time); q.getResult(3,no); q.getResult(4,year); c_genre = q.getResult(5); c_albumartist = q.getResult(6); c_artist = q.getResult(7); c_albumname = q.getResult(8); q.getResult(9,trackyear); q.getResult(10,queue); GMDBTrackItem::max_trackno=FXMAX(GMDBTrackItem::max_digits(GMTRACKNO(no)),GMDBTrackItem::max_trackno); GMDBTrackItem::max_queue=FXMAX(GMDBTrackItem::max_digits(queue),GMDBTrackItem::max_queue); item = new GMDBTrackItem(id,c_title,c_artist,c_albumartist,c_albumname,c_genre,time,no,queue,(FXushort)year,(FXushort)trackyear); tracklist->appendItem(item); } } else { while(q.execute()){ q.getResult(0,id); c_title = q.getResult(1); q.getResult(2,time); q.getResult(3,no); q.getResult(4,year); c_genre = q.getResult(5); c_albumartist = q.getResult(6); c_artist = q.getResult(7); c_albumname = q.getResult(8); q.getResult(9,trackyear); GMDBTrackItem::max_trackno=FXMAX(GMDBTrackItem::max_digits(GMTRACKNO(no)),GMDBTrackItem::max_trackno); item = new GMDBTrackItem(id,c_title,c_artist,c_albumartist,c_albumname,c_genre,time,no,queue++,(FXushort)year,(FXushort)trackyear); tracklist->appendItem(item); } } GMDBTrackItem::max_trackno = tracklist->getFont()->getTextWidth(FXString('8',GMDBTrackItem::max_trackno)); GMDBTrackItem::max_queue = tracklist->getFont()->getTextWidth(FXString('8',GMDBTrackItem::max_digits(queue))); GMDBTrackItem::max_time = tracklist->getFont()->getTextWidth("88:88",5); } catch(FXCompileException &){ tracklist->clearItems(); return false; } catch(FXExecuteException &){ tracklist->clearItems(); return false; } #ifdef DEBUG FXlong end = fxgetticks(); fxmessage("listTracks(): %30lld\n",end-start); #endif return true; } static const FXchar defaults_section[] = "dialog defaults"; class GMEditTrackDialog : public FXDialogBox { FXDECLARE(GMEditTrackDialog) protected: GMTrackDatabase * db; FXuint samemask; FXIntList tracks; GMTrack info; public: GMComboBox * trackartistbox; GMComboBox * albumartistbox; GMComboBox * genrebox; GMComboBox * albumbox; FXTextField * yearfield; FXSpinner * discspinner; FXTextField * discfield; FXTextField * titlefield; FXCheckButton * updatetags; FXCheckButton * updatefilename; FXCheckButton * autonumber; FXSpinner * autonumberoffset; FXSpinner * trackspinner; protected: GMEditTrackDialog(){} private: GMEditTrackDialog(const GMEditTrackDialog&); GMEditTrackDialog &operator=(const GMEditTrackDialog&); public: enum { ID_FILENAME_TEMPLATE=FXDialogBox::ID_LAST }; protected: enum { SAME_ALBUM =0x1, SAME_ARTIST =0x2, SAME_ALBUMARTIST=0x4, SAME_GENRE =0x8, SAME_YEAR =0x10, SAME_DISC =0x20, }; public: long onCmdAccept(FXObject*,FXSelector,void*); long onCmdFilenameTemplate(FXObject*,FXSelector,void*); public: GMEditTrackDialog(FXWindow *,GMTrackDatabase*); virtual ~GMEditTrackDialog(); }; FXDEFMAP(GMEditTrackDialog) GMEditTrackDialogMap[]={ FXMAPFUNC(SEL_COMMAND,GMEditTrackDialog::ID_FILENAME_TEMPLATE,GMEditTrackDialog::onCmdFilenameTemplate), FXMAPFUNC(SEL_COMMAND,GMEditTrackDialog::ID_ACCEPT,GMEditTrackDialog::onCmdAccept) }; FXIMPLEMENT(GMEditTrackDialog,FXDialogBox,GMEditTrackDialogMap,ARRAYNUMBER(GMEditTrackDialogMap)); static const FXchar update_tags_key[] = "track-update-tags"; static const FXchar update_filenames_key[] = "track-update-filenames"; GMEditTrackDialog::GMEditTrackDialog(FXWindow*p,GMTrackDatabase * d) : FXDialogBox(p,FXString::null,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE,0,0,0,0,0,0,0,0,0,0), db(d) { FXPacker * main=NULL; FXTextField * textfield = NULL; FXHorizontalFrame * hframe = NULL; GMTabBook * tabbook = NULL; FXMatrix * matrix = NULL; GMTabFrame * tabframe = NULL; titlefield=NULL; discfield=NULL; discspinner=NULL; setTitle(tr("Edit Track Information")); FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_RIGHT|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,tr("&Cancel"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,tr("&Save"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); GMTrack other; GMTag::Properties prop; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); db->getTrack(tracks[0],info); if (tracks.no()==1) GMTag::properties(info.mrl,prop); samemask=SAME_ALBUM|SAME_ARTIST|SAME_ALBUMARTIST|SAME_GENRE|SAME_YEAR|SAME_DISC; if (tracks.no()>1) { for (FXint i=1;igetTrack(tracks[i],other); if (other.album!=info.album) samemask&=~SAME_ALBUM; if (other.artist!=info.artist) samemask&=~SAME_ARTIST; if (other.album_artist!=info.album_artist) samemask&=~SAME_ALBUMARTIST; if (other.genre!=info.genre) samemask&=~SAME_GENRE; if (other.year!=info.year) samemask&=~SAME_YEAR; if (GMDISCNO(other.no)!=GMDISCNO(info.no)) samemask&=~SAME_DISC; } } if (tracks.no()==1) { /* only show spinner when one track is selected */ main = new FXPacker(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0); } else { new FXSeparator(this,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); main = new FXPacker(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,5,5,5,5); } if (tracks.no()==1) { /* only show spinner when one track is selected */ tabbook = new GMTabBook(main,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); new GMTabItem(tabbook,tr("&Tag"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); tabframe = new GMTabFrame(tabbook); FXMatrix * tagmatrix = new FXMatrix(tabframe,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS,0,0,0,0,10,10,10,10); new GMTabItem(tabbook,tr("&Properties"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); tabframe = new GMTabFrame(tabbook); matrix = new FXMatrix(tabframe,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS,0,0,0,0,10,10,10,10); new FXLabel(matrix,tr("Filename"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); textfield->setText(info.mrl); new FXLabel(matrix,tr("Type"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); textfield->setText(FXPath::extension(info.mrl).upper()); new FXLabel(matrix,tr("Size"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); #if defined(__LP64__) || defined(_LP64) || (_MIPS_SZLONG == 64) || (__WORDSIZE == 64) textfield->setText(GMStringFormat("%'ld",FXStat::size(info.mrl))); #else textfield->setText(GMStringFormat("%'lld",FXStat::size(info.mrl))); #endif new FXLabel(matrix,tr("Bitrate"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); textfield->setText(GMStringFormat("%dkbs",prop.bitrate)); new FXLabel(matrix,tr("Samplerate"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); textfield->setText(GMStringFormat("%dHz",prop.samplerate)); new FXLabel(matrix,tr("Channels"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); textfield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_READONLY); textfield->setText(GMStringFormat("%d",prop.channels)); matrix = tagmatrix; // new FXFrame(matrix,FRAME_NONE,0,0,0,0,0,0,3); // new FXFrame(matrix,FRAME_NONE|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,3); new FXLabel(matrix,tr("Track"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); trackspinner = new GMSpinner(hframe,4,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT); trackspinner->setRange(0,1000); new FXLabel(hframe,tr("Disc"),NULL,LABEL_NORMAL|LAYOUT_LEFT|LAYOUT_CENTER_Y); discspinner = new GMSpinner(hframe,3,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT); discspinner->setRange(0,100); yearfield = new GMTextField(hframe,4,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_RIGHT|TEXTFIELD_INTEGER|TEXTFIELD_LIMITED); new FXLabel(hframe,tr("Year"),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y|LAYOUT_RIGHT); } else { matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS,0,0,0,0,0,0,0,0); if (samemask&SAME_DISC) { new FXLabel(matrix,tr("Disc"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); discspinner = new GMSpinner(hframe,3,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT); discspinner->setRange(0,100); } else { new FXLabel(matrix,tr("Disc"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); discfield = new GMTextField(hframe,3,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT|TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|JUSTIFY_RIGHT); } yearfield = new GMTextField(hframe,4,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_RIGHT|TEXTFIELD_INTEGER|TEXTFIELD_LIMITED|JUSTIFY_RIGHT); new FXLabel(hframe,tr("Year"),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y|LAYOUT_RIGHT); } if (tracks.no()==1) { new FXLabel(matrix,tr("Title"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); titlefield = new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK); } new FXLabel(matrix,tr("&Artist"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); trackartistbox = new GMComboBox(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_THICK|FRAME_SUNKEN); new FXLabel(matrix,tr("Album A&rtist"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); albumartistbox = new GMComboBox(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_THICK|FRAME_SUNKEN); new FXLabel(matrix,tr("Album"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); albumbox = new GMComboBox(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_THICK|FRAME_SUNKEN); new FXLabel(matrix,tr("Genre"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); genrebox = new GMComboBox(hframe,20,NULL,0,LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN); if (tracks.no()>1 && tracks.no()<=0xFFFF) { new FXFrame(matrix,FRAME_NONE); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); autonumber = new GMCheckButton(hframe,tr("Auto track number. Offset:"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL|LAYOUT_CENTER_Y); autonumberoffset = new GMSpinner(hframe,2,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_LEFT); autonumber->setTarget(autonumberoffset); autonumber->setSelector(FXWindow::ID_TOGGLEENABLED); autonumberoffset->disable(); autonumberoffset->setRange(1,99); } new FXFrame(matrix,FRAME_NONE); updatetags = new GMCheckButton(matrix,tr("Update Tag in File"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXFrame(matrix,FRAME_NONE); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); updatefilename = new GMCheckButton(hframe,fxtr("Update Filename"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL|LAYOUT_CENTER_Y); new GMButton(hframe,tr("Set export template…") ,NULL,this,ID_FILENAME_TEMPLATE,FRAME_RAISED,0,0,0,0); updatetags->setCheck(getApp()->reg().readBoolEntry(defaults_section,update_tags_key,false)); updatefilename->setCheck(getApp()->reg().readBoolEntry(defaults_section,update_filenames_key,false)); db->listAlbums(albumbox,db->getTrackAlbum(tracks[0])); albumbox->setSortFunc(album_list_sort); albumbox->setNumVisible(FXMIN(10,albumbox->getNumItems())); albumbox->sortItems(); albumbox->setCurrentItem(-1); db->listArtists(trackartistbox); trackartistbox->setSortFunc(artist_list_sort); trackartistbox->setNumVisible(FXMIN(10,trackartistbox->getNumItems())); trackartistbox->sortItems(); trackartistbox->setCurrentItem(-1); db->listArtists(albumartistbox); albumartistbox->setSortFunc(artist_list_sort); albumartistbox->setNumVisible(FXMIN(10,albumartistbox->getNumItems())); albumartistbox->sortItems(); albumartistbox->setCurrentItem(-1); db->listGenres(genrebox); genrebox->setSortFunc(genre_list_sort); genrebox->setNumVisible(FXMIN(10,genrebox->getNumItems())); genrebox->sortItems(); genrebox->setCurrentItem(-1); if (tracks.no()==1) { trackspinner->setValue(GMTRACKNO(info.no)); albumbox->setCurrentItem(albumbox->findItem(info.album)); trackartistbox->setCurrentItem(trackartistbox->findItem(info.artist)); albumartistbox->setCurrentItem(albumartistbox->findItem(info.album_artist)); genrebox->setCurrentItem(genrebox->findItem(info.genre)); yearfield->setText(GMStringVal(info.year)); titlefield->setText(info.title); discspinner->setValue(GMDISCNO(info.no)); } else { if (samemask&SAME_ALBUM) albumbox->setCurrentItem(albumbox->findItem(info.album)); if (samemask&SAME_ARTIST) trackartistbox->setCurrentItem(trackartistbox->findItem(info.artist)); if (samemask&SAME_ALBUMARTIST) albumartistbox->setCurrentItem(albumartistbox->findItem(info.album_artist)); if (samemask&SAME_GENRE) genrebox->setCurrentItem(genrebox->findItem(info.genre)); if (samemask&SAME_YEAR) yearfield->setText(GMStringVal(info.year)); if (samemask&SAME_DISC) discspinner->setValue(GMDISCNO(info.no)); } } GMEditTrackDialog::~GMEditTrackDialog() { } long GMEditTrackDialog::onCmdFilenameTemplate(FXObject*,FXSelector,void*){ GMFilenameTemplateDialog dialog(this); dialog.execute(); return 1; } long GMEditTrackDialog::onCmdAccept(FXObject*sender,FXSelector sel,void*ptr){ FXbool changed=false; FXbool sync=false; FXint i; FXString field; FXString altfield; FXDialogBox::onCmdAccept(sender,sel,ptr); db->beginEdit(); /// TITLE if (tracks.no()==1) { field=titlefield->getText().trim().simplify(); if (!field.empty() && info.title!=field){ db->setTrackTitle(tracks[0],field); changed=true; } } /// GENRE field=genrebox->getText().trim().simplify(); if (( !field.empty()) && ( ( tracks.no()>1 && ( (!(samemask&SAME_GENRE)) || field!=info.genre )) || ( tracks.no()==1 && info.genre!=field ) )) { db->setTrackGenre(tracks,field); changed=true; sync=true; } /// ARTIST field=trackartistbox->getText().trim().simplify(); if (( !field.empty()) && ( ( tracks.no()>1 && ( (!(samemask&SAME_ARTIST)) || field!=info.artist )) || ( tracks.no()==1 && info.artist!=field ) )) { db->setTrackArtist(tracks,field); changed=true; sync=true; } /// YEAR field=yearfield->getText().trim().simplify(); if (!field.empty()){ #if FOXVERSION >= FXVERSION(1,7,12) FXint year=yearfield->getText().toInt(); #else FXint year=FXIntVal(yearfield->getText()); #endif if ( ( tracks.no()>1 && ( (!(samemask&SAME_YEAR)) || info.year!=year ) ) || ( tracks.no()==1 && info.year!=year )) { db->setTrackYear(tracks,year); changed=true; } } /// DISC and TRACK number if (tracks.no()==1) { if (GMTRACKNO(info.no)!=trackspinner->getValue() || GMDISCNO(info.no)!=discspinner->getValue() ) { db->setTrackDiscNumber(tracks[0],GMALBUMNO(discspinner->getValue(),trackspinner->getValue())); changed=true; sync=true; } } else { if (autonumber->getCheck()) { if (discspinner) { /// all tracks had the same disc number for (i=0;isetTrackDiscNumber(tracks[i],GMALBUMNO(discspinner->getValue(),autonumberoffset->getValue()+i)); } changed=true; sync=true; } else { /// disc field if (discfield->getText().empty()) { for (i=0;isetTrackNumber(tracks[i],autonumberoffset->getValue()+i); } changed=true; sync=true; } else { for (i=0;i= FXVERSION(1,7,12) db->setTrackDiscNumber(tracks[i],GMALBUMNO(discfield->getText().toUInt(),autonumberoffset->getValue()+i)); #else db->setTrackDiscNumber(tracks[i],GMALBUMNO(FXUIntVal(discfield->getText()),autonumberoffset->getValue()+i)); #endif } changed=true; sync=true; } } } else { if (discspinner) { if (GMDISCNO(info.no)!=discspinner->getValue()){ db->setTrackDisc(tracks,discspinner->getValue()); changed=true; sync=true; } } else { // disc field field=discfield->getText().trim().simplify(); if (!field.empty()) { #if FOXVERSION >= FXVERSION(1,7,12) FXint disc=discfield->getText().toInt(); #else FXint disc=FXIntVal(discfield->getText()); #endif db->setTrackDisc(tracks,disc); changed=true; sync=true; } } } } field=albumartistbox->getText().trim().simplify(); altfield=albumbox->getText().trim().simplify(); /// ALBUM ARTIST if (( !field.empty()) && ( ( tracks.no()>1 && ( (!(samemask&SAME_ALBUMARTIST)) || field!=info.album_artist )) || ( tracks.no()==1 && info.album_artist!=field ) )) { if (altfield.empty() && (samemask&SAME_ALBUM)) { altfield=info.album; } db->setTrackAlbumArtist(tracks,field,altfield); changed=true; sync=true; } else if (( !altfield.empty()) && ( ( tracks.no()>1 && ( (!(samemask&SAME_ALBUM)) || altfield!=info.album )) || ( tracks.no()==1 && info.album!=altfield ) )) { db->setTrackAlbum(tracks,altfield,(samemask&SAME_ALBUMARTIST)); changed=true; sync=true; } if (updatetags->getCheck()) { if (changed || (FXMessageBox::question(GMPlayerManager::instance()->getMainWindow(),MBOX_YES_NO,fxtr("Update Tags?"),fxtr("No tracks were updated.\nWould you still like to write the tags for the selected tracks?"))==MBOX_CLICKED_YES)) { GMTrack info; for (i=0;igetTrack(tracks[i],info)) break; info.saveTag(info.mrl); db->setTrackImported(tracks[i],FXThread::time()); } } } if (updatefilename->getCheck()) { updateTrackFilenames(db,tracks); } getApp()->reg().writeBoolEntry(defaults_section,update_tags_key,updatetags->getCheck()); getApp()->reg().writeBoolEntry(defaults_section,update_filenames_key,updatefilename->getCheck()); db->endEdit(sync); GMPlayerManager::instance()->getTrackView()->refresh(); return 1; } long GMDatabaseSource::onCmdEditTrack(FXObject*,FXSelector,void*){ GMEditTrackDialog dialog(GMPlayerManager::instance()->getMainWindow(),db); dialog.execute(); return 1; } long GMDatabaseSource::onCmdFilenameTemplate(FXObject*,FXSelector,void*){ GMFilenameTemplateDialog dialog(FXApp::instance()->getActiveWindow()); dialog.execute(); return 1; } void GMDatabaseSource::getTrackFilenames(const FXIntList & tracks,FXStringList & files){ files.no(tracks.no()); for (int i=0;igetTrackFilename(tracks[i]); } } void GMDatabaseSource::removeFiles(const FXStringList & files) { FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Remove Audio Files?"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,600,400,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Remove Audio Files..."),fxtr("The following audio files are going to be removed")); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Remove"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y); GMScrollFrame * sunken = new GMScrollFrame(main); FXList * list = new GMList(sunken,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); for (int i=0;iappendItem(files[i]); } if (dialog.execute()) { for (int i=0;ireg().readStringEntry("Settings","last-export-directory",FXSystem::getHomeDirectory().text()); FXString title; FXuint opts=0; if (getPlayList()==-1) title=fxtr("Export Main Library"); else title=fxtr("Export Play List"); GMExportDialog dialog(GMPlayerManager::instance()->getMainWindow(),title); dialog.setDirectory(searchdir); dialog.setSelectMode(SELECTFILE_ANY); dialog.setPatternList(patterns); dialog.setCurrentPattern(0); #if FOXVERSION < FXVERSION(1,7,20) dialog.setMatchMode(FILEMATCH_CASEFOLD); #else dialog.setMatchMode(FXPath::CaseFold); #endif dialog.setRelativePath(FXApp::instance()->reg().readBoolEntry("Settings","export-relative-paths",false)); if (dialog.execute()){ if (FXStat::exists(dialog.getFilename())){ if (FXMessageBox::question(GMPlayerManager::instance()->getMainWindow(),MBOX_YES_NO,fxtr("Overwrite File?"),fxtr("File already exists. Would you like to overwrite it?"))!=MBOX_CLICKED_YES) return 1; } if (dialog.getRelativePath()) opts|=PLAYLIST_OPTIONS_RELATIVE; FXApp::instance()->reg().writeStringEntry("Settings","last-export-directory",dialog.getDirectory().text()); FXApp::instance()->reg().writeBoolEntry("Settings","export-relative-paths",dialog.getRelativePath()); FXApp::instance()->beginWaitCursor(); switch(dialog.getCurrentPattern()){ case 0: db->exportList(dialog.getFilename(),getPlayList(),PLAYLIST_XSPF,opts); break; case 1: db->exportList(dialog.getFilename(),getPlayList(),PLAYLIST_PLS,opts); break; case 2: db->exportList(dialog.getFilename(),getPlayList(),PLAYLIST_M3U_EXTENDED,opts); break; case 3: db->exportList(dialog.getFilename(),getPlayList(),PLAYLIST_M3U,opts); break; case 4: db->exportList(dialog.getFilename(),getPlayList(),PLAYLIST_CSV,opts); break; } FXApp::instance()->endWaitCursor(); } return 1; } long GMDatabaseSource::onUpdExport(FXObject*sender,FXSelector,void*){ sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); return 1; } long GMDatabaseSource::onCmdExportTracks(FXObject*,FXSelector sel,void*){ const FXuint labelstyle=LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT; FXIntList tracks; if (FXSELID(sel)==ID_EXPORT_TRACK) { GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); } else { GMPlayerManager::instance()->getTrackView()->getTracks(tracks); } if (tracks.no()==0) return 1; FXString title; FXString subtitle; switch(FXSELID(sel)){ case ID_EXPORT_GENRE: title=fxtr("Export Genre"); subtitle=fxtr("Export tracks with genre to destination directory."); break; case ID_EXPORT_ARTIST:title=fxtr("Export Artists"); subtitle=fxtr("Export tracks from artist to destination directory."); break; case ID_EXPORT_ALBUM: title=fxtr("Export Albums"); subtitle=fxtr("Export tracks from album to destination directory."); break; case ID_EXPORT_TRACK: title=fxtr("Export Tracks"); subtitle=fxtr("Export tracks to destination directory."); break; default: FXASSERT(0); break; } // FXTextField * textfield; FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),title,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,title,subtitle,NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Export"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXMatrix * matrix = new FXMatrix(main,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,0,0,4,0); /* new FXLabel(matrix,"Directory:",NULL,labelstyle); FXHorizontalFrame * hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); FXTextField * textfield = new FXTextField(hframe,20,NULL,0,LAYOUT_FILL_X|TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK); new FXButton(hframe,… "\tSelect Directory",NULL,NULL,0); */ new FXLabel(matrix,fxtr("Template:"),NULL,labelstyle); new GMTextField(matrix,20,NULL,0,LAYOUT_FILL_X|TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN); // textfield->setFont(font_fixed); new FXLabel(matrix,fxtr("Encoding:"),NULL,labelstyle); GMListBox * list_codecs = new GMListBox(matrix,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN); for (int i=0;gmcodecnames[i]!=NULL;i++) list_codecs->appendItem(gmcodecnames[i]); list_codecs->setNumVisible(9); new FXLabel(matrix,fxtr("Options:"),NULL,labelstyle); new GMCheckButton(matrix,fxtr("Replace spaces with underscores"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,fxtr("Lower case"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,fxtr("Lower case extension"),NULL,0,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); if (dialog.execute()){ } return 1; } long GMDatabaseSource::onCmdDelete(FXObject*,FXSelector sel,void*){ FXIntList tracks; FXIntList selected; FXStringList files; if (FXSELID(sel)==ID_DELETE_TRACK) { GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); } else { GMPlayerManager::instance()->getTrackView()->getTracks(tracks); } if (tracks.no()==0) return 1; FXString title; FXString subtitle; switch(FXSELID(sel)){ case ID_DELETE_GENRE: title=fxtr("Remove Genre?"); subtitle=fxtr("Remove tracks with genre from library?"); GMPlayerManager::instance()->getTrackView()->getSelectedGenres(selected); if (selected.no()==0) return 1; break; case ID_DELETE_ARTIST:title=fxtr("Remove Artist?"); subtitle=fxtr("Remove tracks from artist from library?"); GMPlayerManager::instance()->getTrackView()->getSelectedArtists(selected); if (selected.no()==0) return 1; break; case ID_DELETE_ALBUM: title=fxtr("Remove Album?"); subtitle=fxtr("Remove tracks from album from library?"); GMPlayerManager::instance()->getTrackView()->getSelectedAlbums(selected); if (selected.no()==0) return 1; break; case ID_DELETE_TRACK: title=fxtr("Remove Track(s)?"); subtitle=fxtr("Remove track(s) from library?"); break; default: FXASSERT(0); break; } FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),title,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,title,subtitle,NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Remove"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXCheckButton * from_disk = new GMCheckButton(main,fxtr("Remove tracks from disk")); from_disk->setCheck(FXApp::instance()->reg().readBoolEntry("delete dialog","from-disk",false)); if (dialog.execute()){ db->beginDelete(); if (from_disk->getCheck()) getTrackFilenames(tracks,files); switch(FXSELID(sel)){ case ID_DELETE_GENRE: if (!db->removeGenre(selected[0])) FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtr("Unable to remove genre from the library")); break; case ID_DELETE_ARTIST: if (!db->removeArtist(selected[0])) FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtr("Unable to remove artist from the library")); break; case ID_DELETE_ALBUM: if (!db->removeAlbum(selected[0])) FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtr("Unable to remove album from the library")); break; case ID_DELETE_TRACK: if (!db->removeTracks(tracks)) FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtr("Unable to remove track from the library.")); break; default: FXASSERT(0); break; } if (from_disk->getCheck()) removeFiles(files); FXApp::instance()->reg().writeBoolEntry("delete dialog","from-disk",from_disk->getCheck()); db->endDelete(); GMPlayerManager::instance()->getTrackView()->refresh(); } return 1; } long GMDatabaseSource::onCmdCopyArtistAlbum(FXObject*,FXSelector,void*){ FXDragType types[4]={GMClipboard::trackdatabase,GMClipboard::kdeclipboard,GMClipboard::gnomeclipboard,FXWindow::urilistType}; GMDatabaseClipboardData * data = new GMDatabaseClipboardData; if (GMClipboard::instance()->acquire(this,types,4,data)){ FXApp::instance()->beginWaitCursor(); data->db=db; GMPlayerManager::instance()->getTrackView()->getTracks(data->tracks); FXApp::instance()->endWaitCursor(); } else { delete data; FXApp::instance()->beep(); } return 1; } long GMDatabaseSource::onCmdCopyTrack(FXObject*,FXSelector,void*){ FXDragType types[4]={GMClipboard::trackdatabase,GMClipboard::kdeclipboard,GMClipboard::gnomeclipboard,FXWindow::urilistType}; GMDatabaseClipboardData * data = new GMDatabaseClipboardData; if (GMClipboard::instance()->acquire(this,types,4,data)){ FXApp::instance()->beginWaitCursor(); data->db=db; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(data->tracks); FXApp::instance()->endWaitCursor(); } else { delete data; FXApp::instance()->beep(); } return 1; } long GMDatabaseSource::onCmdRequestArtistAlbum(FXObject*sender,FXSelector,void*ptr){ FXEvent* event=(FXEvent*)ptr; FXWindow*window=(FXWindow*)sender; if(event->target==GMClipboard::urilistType){ FXStringList filenames; FXIntList tracks; FXString uri; GMPlayerManager::instance()->getTrackView()->getTracks(tracks); db->getTrackFilenames(tracks,filenames); gm_convert_filenames_to_uri(filenames,uri); window->setDNDData(FROM_DRAGNDROP,event->target,uri); return 1; } else if (event->target==GMClipboard::kdeclipboard){ window->setDNDData(FROM_DRAGNDROP,event->target,"0"); // copy return 1; } return 0; } long GMDatabaseSource::onCmdRequestTrack(FXObject*sender,FXSelector,void*ptr){ FXEvent* event=(FXEvent*)ptr; FXWindow*window=(FXWindow*)sender; if(event->target==GMClipboard::urilistType){ FXStringList filenames; FXIntList tracks; FXString uri; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); db->getTrackFilenames(tracks,filenames); gm_convert_filenames_to_uri(filenames,uri); window->setDNDData(FROM_DRAGNDROP,event->target,uri); return 1; } else if (event->target==GMClipboard::kdeclipboard){ window->setDNDData(FROM_DRAGNDROP,event->target,"0"); // copy return 1; } return 0; } long GMDatabaseSource::onCmdDrop(FXObject*sender,FXSelector,void*){ FXWindow * window=(FXWindow*)sender; FXString files; FXStringList filelist; // FXbool from_kde=false; FXbool from_uri=false; FXDragType * types; FXuint ntypes; if (getPlayList()==-1 && FXApp::instance()->getDragWindow()) return 0; if (window->inquireDNDTypes(FROM_DRAGNDROP,types,ntypes)){ for (FXuint i=0;igetDragTypeName(types[i]).text()); // if (types[i]==GMClipboard::kdeclipboard) from_kde=true; if (types[i]==FXWindow::urilistType) from_uri=true; } // else if (from_kde && from_uri) { // } if (from_uri) { if (window->getDNDData(FROM_DRAGNDROP,FXWindow::urilistType,files)){ gm_convert_uri_to_filenames(files,filelist); } } window->dropFinished(DRAG_ACCEPT); if (filelist.no()) { GMImportDialog dialog(GMPlayerManager::instance()->getMainWindow(),IMPORT_FROMPASTE); if (dialog.execute()) { GMPlayerManager::instance()->stop(); GMImportDatabase searchdialog(GMPlayerManager::instance()->getMainWindow(),filelist,GMPlayerManager::instance()->getPreferences().import,getPlayList(),GMPlayerManager::instance()->getMainWindow()->getThickFont()); searchdialog.execute(); GMPlayerManager::instance()->getTrackView()->refresh(); } } else { FXApp::instance()->beep(); } } return 1; } long GMDatabaseSource::onCmdPaste(FXObject*,FXSelector,void*){ FXString files; FXStringList filelist; FXDragType * types; FXuint num; // FXbool from_db=false; FXbool from_kde=false; FXbool from_gnome=false; FXbool from_uri=false; GMClipboard * clipboard = GMClipboard::instance(); if (clipboard->inquireDNDTypes(FROM_CLIPBOARD,types,num)){ for (FXuint i=0;ihasClipboard() ) { return 1; } if (from_gnome) { if (clipboard->getDNDData(FROM_CLIPBOARD,GMClipboard::gnomeclipboard,files)){ gm_convert_gnomeclipboard_to_filenames(files,filelist); } } else if (from_kde && from_uri) { if (clipboard->getDNDData(FROM_CLIPBOARD,GMClipboard::kdeclipboard,files)){ #ifdef DEBUG if (files=="1") { fxmessage("We do not cut files...\n"); } #endif } if (clipboard->getDNDData(FROM_CLIPBOARD,FXWindow::urilistType,files)){ gm_convert_uri_to_filenames(files,filelist); } } if (filelist.no()){ GMImportDialog dialog(GMPlayerManager::instance()->getMainWindow(),IMPORT_FROMPASTE); if (dialog.execute()) { GMPlayerManager::instance()->stop(); GMImportDatabase searchdialog(GMPlayerManager::instance()->getMainWindow(),filelist,GMPlayerManager::instance()->getPreferences().import,getPlayList(),GMPlayerManager::instance()->getMainWindow()->getThickFont()); searchdialog.execute(); GMPlayerManager::instance()->getTrackView()->refresh(); } } else { FXApp::instance()->beep(); } return 1; } return 0; } long GMDatabaseSource::onUpdPaste(FXObject*,FXSelector,void*){ return 1; } long GMDatabaseSource::onCmdNewPlayList(FXObject*,FXSelector,void*){ FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Create Playlist"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Create Playlist"),fxtr("Specify name of the new playlist"),NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Create"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXMatrix * matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS); new FXLabel(matrix,fxtr("Name"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXTextField * name_field = new GMTextField(matrix,20,&dialog,FXDialogBox::ID_ACCEPT,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_ENTER_ONLY); name_field->setText(fxtr("New Playlist")); name_field->setSelection(0,name_field->getText().length()); dialog.create(); gm_focus_and_select(name_field); if (dialog.execute()) { FXString label= name_field->getText().trim(); if (!label.empty()) { FXint pl; db->insertPlaylist(label,pl); GMPlayerManager::instance()->insertSource(new GMPlayListSource(db,pl)); GMPlayerManager::instance()->getSourceView()->refresh(); } } return 1; } long GMDatabaseSource::onCmdImportPlayList(FXObject*,FXSelector,void*){ GMImportDialog dialog(GMPlayerManager::instance()->getMainWindow(),IMPORT_FROMFILE|IMPORT_PLAYLIST); if (dialog.execute()){ FXString buffer; FXStringList urls; if (gm_buffer_file(dialog.getFilename(),buffer)) { FXString title; FXString extension = FXPath::extension(dialog.getFilename()); if (comparecase(extension,"m3u")==0) gm_parse_m3u(buffer,urls); else if (comparecase(extension,"pls")==0) gm_parse_pls(buffer,urls); else gm_parse_xspf(buffer,urls,title); if (urls.no()) { gm_make_absolute_path(FXPath::directory(dialog.getFilename()),urls); title.trim(); if (title.empty()) title = FXPath::title(dialog.getFilename()); FXint pl = GMPlayerManager::instance()->createPlaylist(title); GMImportDatabase searchdialog(GMPlayerManager::instance()->getMainWindow(),urls,GMPlayerManager::instance()->getPreferences().import,pl,GMPlayerManager::instance()->getMainWindow()->getThickFont()); searchdialog.execute(); GMPlayerManager::instance()->getTrackView()->refresh(); } } } return 1; } long GMDatabaseSource::onCmdClear(FXObject*,FXSelector,void*){ FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Clear Music Library?"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Clear Music Library?"),fxtr("Remove all tracks from the music library?"),NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Remove All"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXCheckButton * playlist_check = new GMCheckButton(main,fxtr("Keep play lists")); playlist_check->setCheck(FXApp::instance()->reg().readBoolEntry("clear dialog","keep-play-lists",true)); if (dialog.execute()){ GMPlayerManager::instance()->stop(); db->clearTracks(!playlist_check->getCheck()); GMPlayerManager::instance()->removePlayListSources(); GMPlayerManager::instance()->getSourceView()->refresh(); GMPlayerManager::instance()->getTrackView()->refresh(); FXApp::instance()->reg().writeBoolEntry("clear dialog","keep-play-lists",playlist_check->getCheck()); } return 1; } long GMDatabaseSource::onCmdInfo(FXObject*,FXSelector,void*){ FXint num_tracks = db->getNumTracks(); FXint num_albums= db->getNumAlbums(); FXint num_artists= db->getNumArtists(); FXint time = db->getTotalTime(); FXint days = (FXint) floor((double)time/86400.0); time -= (FXint) (86400.0*days); FXint hours = (FXint) floor((double)time/3600.0); time -= (FXint) (3600.0*hours); FXint minutes = (FXint) floor((double)time/60.0); time -= (FXint) (60.0*minutes); FXint seconds = (FXint) floor((double)time); FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Music Library Information"),DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Music Library Information"),fxtr("You music collection consists of…")); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Close"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_CENTER_X|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,20,10,5,5); FXMatrix * matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS); FXLabel * label = new FXLabel(matrix,fxtr("Tracks:"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); label = new FXLabel(matrix,GMStringVal(num_tracks),NULL,LABEL_NORMAL|JUSTIFY_LEFT); label->setTextColor(FXRGB(0,0,255)); new FXLabel(matrix,fxtr("Artists:"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); label = new FXLabel(matrix,GMStringVal(num_artists),NULL,LABEL_NORMAL|JUSTIFY_LEFT); label->setTextColor(FXRGB(0,0,255)); new FXLabel(matrix,fxtr("Albums:"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); label = new FXLabel(matrix,GMStringVal(num_albums),NULL,LABEL_NORMAL|JUSTIFY_LEFT); label->setTextColor(FXRGB(0,0,255)); new FXLabel(matrix,fxtr("Total Time:"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXString duration; if (days) { if (days>=2) duration+=GMStringFormat("%d days",days); else duration+=GMStringFormat("%d day",days); if (seconds==0 && minutes==0 && hours) duration+="."; else duration+=", "; } if (hours) { if (hours>=2) duration+=GMStringFormat("%d hours",hours); else duration+=GMStringFormat("%d hour",hours); if (seconds==0 && minutes==0) duration+="."; else duration+=", "; } if (minutes) { if (minutes>=2) duration+=GMStringFormat("%d minutes",minutes); else duration+=GMStringFormat("%d minute",minutes); if (seconds==0) duration+="."; else duration+=", "; } if (seconds) { if (seconds>=2) duration+=GMStringFormat("%d seconds. ",seconds); else duration+=GMStringFormat("%d second.",seconds); } new FXLabel(matrix,duration,NULL,LABEL_NORMAL|JUSTIFY_LEFT); dialog.execute(); return 1; } long GMDatabaseSource::onCmdTrackPlayed(FXObject*,FXSelector,void*) { FXTRACE((60,"%s::onCmdTrackPlayed\n",getClassName())); FXASSERT(current_track>=0); FXlong timestamp = (FXlong)FXThread::time(); db->playedTrack(current_track,timestamp); GMTrack info; if (getTrack(info) && GMPlayerManager::instance()->getAudioScrobbler()) GMPlayerManager::instance()->getAudioScrobbler()->submit(timestamp,info); return 1; } long GMDatabaseSource::onCmdOpenFolder(FXObject*,FXSelector,void*){ FXIntList tracks; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); if (tracks.no()==1) { gm_open_folder(FXPath::directory(db->getTrackFilename(tracks[0]))); } return 1; } gogglesmm-0.12.7/src/main.cpp0000644000175000001440000001067111446275451014542 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMList.h" #include "GMSource.h" #include "GMPlayerManager.h" /* Display Help/Version returns true if application may exit TODO expand to all possible options */ static bool gm_display_help(int argc,char * argv[]) { for (int i=1;i0) fxmessage("Usage: %s [options]\n\n",FXPath::name(argv[0]).text()); else fxmessage("Usage: gogglesmm [options]\n\n"); fxmessage("General options:\n" " -h, --help Display this help page\n" " -v, --version Display version information\n" " --tray Start minimized to tray\n" " --disable-opengl Disables opengl based features\n" "\n" "Control running music manager:\n" " --play Start playback\n" " --play-pause Toggle pause / playback.\n" " --pause Pause playback\n" " --previous Play previous track\n" " --next Play next track\n" " --stop Stop playback\n" " --raise Try to raise the main window\n" " --toggle-shown Show or Hide the main window\n" " --now-playing Show now playing notification\n" "\n" "Debugging options:\n" " --xine-debug Output xine debug info\n" ); return true; } else if ( (comparecase(argv[i],"--version")==0) || (comparecase(argv[i],"-v")==0) ) { fxmessage("Goggles Music Manager %s\n",APPLICATION_VERSION_STRING); return true; } } return false; } int main(int argc,char *argv[]){ /// Check and make sure we're linked correctly to FOX /// If we're not linked correctly, we cannot obviously popup a dialog... if (fxversion[0]==1 && (fxversion[1]==6) ) { /// Test for Stable Version of FOX 1.6 if (FOX_MAJOR!=fxversion[0] || FOX_MINOR!=fxversion[1]){ fxwarning("FOX Header (v%d.%d.%d) / Library (v%d.%d.%d) mismatch! -\n",FOX_MAJOR,FOX_MINOR,FOX_LEVEL,fxversion[0],fxversion[1],fxversion[2]); return 1; } } else if (fxversion[0]==1 && ( fxversion[1]==7)) { /// Test for Development version of FOX 1.7 if (FOX_MAJOR!=fxversion[0] || FOX_MINOR!=fxversion[1] || FOX_LEVEL!=fxversion[2]) { fxwarning("FOX Header (v%d.%d.%d) / Library (v%d.%d.%d) mismatch! -\n",FOX_MAJOR,FOX_MINOR,FOX_LEVEL,fxversion[0],fxversion[1],fxversion[2]); return 1; } } else { fxwarning("Goggles Music Manager linked to a unknown/unsupported version of the FOX Library (v%d.%d.%d)",fxversion[0],fxversion[1],fxversion[2]); return 1; } /// Display Help if (gm_display_help(argc,argv)) return 0; /// Main Application GMPlayerManager gogglesmm; return gogglesmm.run(argc,argv); } gogglesmm-0.12.7/src/GMPreferencesDialog.h0000644000175000001440000001124711667277640017077 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMPREFERENCESDIALOG_H #define GMPREFERENCESDIALOG_H class GMPreferencesDialog : public FXDialogBox { FXDECLARE(GMPreferencesDialog) protected: FXDataTarget target_closeishide; FXDataTarget target_keywords; FXDataTarget target_close_audio; FXDataTarget target_pause_close_device; FXDataTarget target_gapless; FXDataTarget target_replaygain; FXDataTarget target_open_device_on_startup; FXDataTarget target_show_playing_albumcover; FXDataTarget target_show_albumcovers; #ifdef HAVE_DBUS FXDataTarget target_dbus_notify_daemon; #endif FXDataTarget target_gui_tray_icon; FXDataTarget target_gui_show_playing_titlebar; FXDataTarget target_gui_format_title; protected: FXString keywords; public: FXTextField * lastfm_username; FXTextField * lastfm_password; FXLabel * lastfm_password_label; FXLabel * lastfm_username_label; FXCheckButton * lastfm_scrobble; FXButton * lastfm_join; FXTextField * iconthemedir; FXCheckButton * check_audio_normalization; FXCheckButton * browser_icons; FXCheckButton * statusbarbutton; FXCheckButton * toolbar_bigicons; FXCheckButton * toolbar_showlabels; FXList * colorpresets; GMListBox * toolbar_docktop; GMListBox * driverlist; GMListBox * themelist; GMListBox * lastfm_service; FXbool password_set; FXFont * selectedfont; FXint theme; ColorTheme current; ColorTheme selected; public: enum { ID_LASTFM_USERNAME= FXDialogBox::ID_LAST, ID_LASTFM_PASSWORD, ID_LASTFM_SCROBBLE, ID_LASTFM_SERVICE, ID_LASTFM_JOIN, ID_BASE_COLOR, ID_BACK_COLOR, ID_FORE_COLOR, ID_SHADOW_COLOR, ID_HILITE_COLOR, ID_SEL_BACK_COLOR, ID_SEL_FORE_COLOR, ID_MENU_BACK_COLOR, ID_MENU_FORE_COLOR, ID_TIP_BACK_COLOR, ID_TIP_FORE_COLOR, ID_SOURCE_BACK_COLOR, ID_SOURCE_FORE_COLOR, ID_PLAY_BACK_COLOR, ID_PLAY_FORE_COLOR, ID_ALTERNATIVE_BACK_COLOR, ID_TRAY_COLOR, ID_BORDER_COLOR, ID_COLOR_THEME, ID_FONT, ID_CHANGE_FONT, ID_AUDIO_DRIVER, ID_REPLAY_GAIN, ID_ICON_THEME, }; public: long onCmdLastFMScrobble(FXObject*,FXSelector,void*); long onCmdLastFMUserName(FXObject*,FXSelector,void*); long onCmdLastFMPassWord(FXObject*,FXSelector,void*); long onFocusLastFMPassWord(FXObject*,FXSelector,void*); long onCmdLastFMService(FXObject*,FXSelector,void*); long onCmdLastFMJoin(FXObject*,FXSelector,void*); long onCmdElementColor(FXObject*,FXSelector,void*); long onUpdElementColor(FXObject*,FXSelector,void*); long onCmdColorTheme(FXObject*,FXSelector,void*); long onUpdColorTheme(FXObject*,FXSelector,void*); long onUpdFont(FXObject*,FXSelector,void*); long onCmdChangeFont(FXObject*,FXSelector,void*); long onCmdAccept(FXObject*,FXSelector,void*); long onCmdAudioDriver(FXObject*,FXSelector,void*); long onCmdReplayGain(FXObject*,FXSelector,void*); long onCmdIconTheme(FXObject*,FXSelector,void*); protected: GMPreferencesDialog(){} private: GMPreferencesDialog(const GMPreferencesDialog&); GMPreferencesDialog &operator=(const GMPreferencesDialog&); public: GMPreferencesDialog(FXWindow * p); void initColorThemes(); void updateColorThemes(); void updateColors(); void updateFonts(); void redraw(); virtual ~GMPreferencesDialog(); }; #endif gogglesmm-0.12.7/src/GMRemote.h0000644000175000001440000000532711525430601014730 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMREMOTE_H #define GMREMOTE_H class GMWindow; class GMRemote : public FXMainWindow { FXDECLARE(GMRemote) private: FXTextField * title_label; FXTextField * artistalbum_label; FX7Segment * time_label; FXImageFrame* cover_label; FXPopupPtr volumecontrol; FXMenuButton* volumebutton; FXSlider * volumeslider; FXFontPtr font_title; FXImagePtr img_default; FXIconPtr icon_volume_high; FXIconPtr icon_volume_medium; FXIconPtr icon_volume_low; FXIconPtr icon_volume_muted; FXIconPtr icon_home; protected: virtual bool doesOverrideRedirect() const; GMRemote() {} public: long onCmdVolume(FXObject*,FXSelector,void*); long onCmdVolumeButton(FXObject*,FXSelector,void*); long onUpdVolumeButton(FXObject*,FXSelector,void*); public: enum { ID_VOLUME_SLIDER = FXMainWindow::ID_LAST, ID_VOLUME_BUTTON, }; public: /// Construct Remote Window GMRemote(FXApp* a,FXObject*,FXSelector); void updateCover(FXImage * img); // Update Display void display(const GMTrack & track); void elapsed_time(FXint h,FXint m,FXint s,FXint p,FXbool playing); void update_volume_display(FXint l); void reset(); void writeRegistry(); /// Create virtual void create(); /// Destroy calculator virtual ~GMRemote(); }; #endif gogglesmm-0.12.7/src/GMPlayerManager.cpp0000644000175000001440000013513612063214635016566 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include "icons.h" #include "gmdefs.h" #ifdef HAVE_DBUS #include "GMDBus.h" #include "GMNotifyDaemon.h" #include "GMMediaPlayerService.h" #include "GMSettingsDaemon.h" #include "gogglesmm_xml.h" #endif #include #include "GMApp.h" #include "GMPlayer.h" #include "GMAbout.h" #include "GMWindow.h" #include "GMTrackList.h" #include "GMRemote.h" #include "GMTag.h" #include "GMThread.h" #include "GMSearch.h" #include "GMList.h" #include "GMTrackView.h" #include "GMSource.h" #include "GMTrackDatabase.h" #include "GMDatabaseSource.h" #include "GMStreamSource.h" #include "GMPlayListSource.h" #include "GMIconTheme.h" #include "GMPlayerManager.h" #include "GMFetch.h" #include "GMEQDialog.h" #include "GMTrayIcon.h" #include "GMSourceView.h" #include "GMAudioScrobbler.h" enum { FIFO_STATUS_ERROR = 0, FIFO_STATUS_OWNER = 1, FIFO_STATUS_EXISTS = 2 }; #if APPLICATION_BETA_DB > 0 #define DATABASE_FILENAME "goggles_beta.db" #else #define DATABASE_FILENAME "goggles.db" #endif FXDEFMAP(GMPlayerManager) GMPlayerManagerMap[]={ FXMAPFUNC(SEL_TIMEOUT,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY,GMPlayerManager::onUpdTrackDisplay), FXMAPFUNC(SEL_TIMEOUT,GMPlayerManager::ID_HANDLE_EVENTS,GMPlayerManager::onUpdEvents), FXMAPFUNC(SEL_TIMEOUT,GMPlayerManager::ID_SLEEP_TIMER,GMPlayerManager::onCmdSleepTimer), FXMAPFUNC(SEL_TIMEOUT,GMPlayerManager::ID_PLAY_NOTIFY,GMPlayerManager::onPlayNotify), FXMAPFUNC(SEL_IO_READ,GMPlayerManager::ID_DDE_MESSAGE,GMPlayerManager::onDDEMessage), FXMAPFUNC(SEL_CHORE,GMPlayerManager::ID_PLAYER_ERROR,GMPlayerManager::onPlayerError), FXMAPFUNC(SEL_CLOSE,GMPlayerManager::ID_WINDOW,GMPlayerManager::onCmdCloseWindow), FXMAPFUNC(SEL_SIGNAL,GMPlayerManager::ID_CHILD,GMPlayerManager::onCmdChild), FXMAPFUNC(SEL_COMMAND,GMPlayerManager::ID_SCROBBLER,GMPlayerManager::onScrobblerError), FXMAPFUNC(SEL_OPENED,GMPlayerManager::ID_SCROBBLER,GMPlayerManager::onScrobblerOpen), FXMAPFUNC(SEL_COMMAND,GMPlayerManager::ID_EQUALIZER,GMPlayerManager::onCmdEqualizer), FXMAPFUNC(SEL_COMMAND,GMPlayerManager::ID_SHOW_MANAGER,GMPlayerManager::onCmdShowManager), #ifdef HAVE_DBUS FXMAPFUNC(SEL_KEYPRESS,GMPlayerManager::ID_GNOME_SETTINGS_DAEMON,GMPlayerManager::onCmdSettingsDaemon), #endif FXMAPFUNC(SEL_COMMAND,GMPlayerManager::ID_DOWNLOAD_COMPLETE,GMPlayerManager::onCmdDownloadComplete) }; FXIMPLEMENT(GMPlayerManager,FXObject,GMPlayerManagerMap,ARRAYNUMBER(GMPlayerManagerMap)) #ifdef HAVE_DBUS #define GOGGLESMM_DBUS_NAME "org.fifthplanet.gogglesmm" #define GOGGLESMM_DBUS_PATH "/org/fifthplanet/gogglesmm" #define GOGGLESMM_DBUS_INTERFACE "org.fifthplanet.gogglesmm" DBusHandlerResult dbus_systembus_filter(DBusConnection *,DBusMessage * msg,void * data){ FXTRACE((80,"------------\n")); FXTRACE((80,"path: %s\n",dbus_message_get_path(msg))); FXTRACE((80,"member: \"%s\"\n",dbus_message_get_member(msg))); FXTRACE((80,"interface: %s\n",dbus_message_get_interface(msg))); FXTRACE((80,"sender: %s\n",dbus_message_get_sender(msg))); GMPlayerManager * p = (GMPlayerManager*)data; if (dbus_message_has_path(msg,"/org/freedesktop/NetworkManager")){ if (dbus_message_is_signal(msg,"org.freedesktop.NetworkManager","StateChanged") || dbus_message_is_signal(msg,"org.freedesktop.NetworkManager","StateChange")) { FXuint state=0; enum { /* // Network Manager 0.7 / 0.8 NM7_STATE_UNKNOWN = 0, NM7_STATE_ASLEEP = 1, NM7_STATE_CONNECTING = 2, NM7_STATE_CONNECTED = 3, NM7_STATE_DISCONNECTED = 4, // Network Manager 0.9 NM9_STATE_UNKNOWN = 0, NM9_STATE_ASLEEP = 10, NM9_STATE_DISCONNECTED = 20, NM9_STATE_DISCONNECTING = 30, NM9_STATE_CONNECTING = 40, NM9_STATE_CONNECTED_LOCAL = 50, NM9_STATE_CONNECTED_SITE = 60, NM9_STATE_CONNECTED_GLOBAL = 70, */ NM7_STATE_CONNECTED = 3, NM9_STATE_CONNECTED_GLOBAL = 70, }; if (dbus_message_get_args(msg,NULL,DBUS_TYPE_UINT32,&state,DBUS_TYPE_INVALID)) { if (p->getAudioScrobbler() && (state==NM7_STATE_CONNECTED || state==NM9_STATE_CONNECTED_GLOBAL)) p->getAudioScrobbler()->nudge(); } return DBUS_HANDLER_RESULT_HANDLED; } } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } DBusHandlerResult dbus_playermanager_filter(DBusConnection *connection,DBusMessage * msg,void * data){ FXchar * mrl; GMPlayerManager * p = (GMPlayerManager*)data; if (dbus_message_has_path(msg,GOGGLESMM_DBUS_PATH)){ if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"play")){ p->cmd_play(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"playpause")){ p->cmd_playpause(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"stop")){ p->cmd_stop(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"pause")){ p->cmd_pause(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"next")){ p->cmd_next(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"prev")){ p->cmd_prev(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"open")){ if (dbus_message_get_args(msg,NULL,DBUS_TYPE_STRING,&mrl,DBUS_TYPE_INVALID)) { p->open(mrl); } return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"raise")){ if (p->getMainWindow()->shown()) p->getMainWindow()->raise(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"notify")){ p->display_track_notification(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"toggleshown")){ p->cmd_toggle_shown(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"getactions")){ FXuint actions=0; enum { CAN_PLAY = 0x1, CAN_PAUSE = 0x2, CAN_STOP = 0x4, CAN_NEXT = 0x8, CAN_PREV = 0x10, }; if (p->can_play() || p->can_unpause()) actions|=CAN_PLAY; if (p->can_stop()) actions|=CAN_STOP; if (p->can_pause()) actions|=CAN_PAUSE; if (p->can_prev()) actions|=CAN_PREV; if (p->can_next()) actions|=CAN_NEXT; return gm_dbus_reply_unsigned_int(connection,msg,actions); } else if (dbus_message_is_method_call(msg,GOGGLESMM_DBUS_INTERFACE,"exit")){ gm_dbus_reply_if_needed(connection,msg); if (p->getMainWindow()) p->getMainWindow()->handle(p,FXSEL(SEL_COMMAND,GMWindow::ID_QUIT),NULL); return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(msg,"org.freedesktop.DBus.Introspectable","Introspect")){ return gm_dbus_reply_string(connection,msg,gogglesmm_xml); } } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } DBusObjectPathVTable org_fifthplanet_gogglesmm={ NULL, &dbus_playermanager_filter, NULL, NULL, NULL, NULL }; void dbus_send_to_self(DBusConnection * connection,const FXchar * signal,FXString argument) { DBusMessage * msg; msg = dbus_message_new_method_call(GOGGLESMM_DBUS_NAME,GOGGLESMM_DBUS_PATH,GOGGLESMM_DBUS_INTERFACE,signal); if (msg){ if (!argument.empty()) { const FXchar * arg=argument.text(); dbus_message_append_args(msg,DBUS_TYPE_STRING,&arg,DBUS_TYPE_INVALID); } dbus_message_set_no_reply(msg,true); dbus_connection_send(connection,msg,NULL); dbus_connection_flush(connection); dbus_message_unref(msg); } } FXint dbus_send_commands(DBusConnection * connection,int& argc,char** argv){ FXString cmd="raise"; FXString url; if (argc>1) { if (compare(argv[1],"--previous")==0) cmd="prev"; else if (compare(argv[1],"--play")==0) cmd="play"; else if (compare(argv[1],"--play-pause")==0) cmd="playpause"; else if (compare(argv[1],"--pause")==0) cmd="pause"; else if (compare(argv[1],"--next")==0) cmd="next"; else if (compare(argv[1],"--stop")==0) cmd="stop"; else if (compare(argv[1],"--toggle-shown")==0) cmd="toggleshown"; else if (compare(argv[1],"--raise")==0) cmd="raise"; else if (compare(argv[1],"--now-playing")==0) cmd="notify"; else { cmd="open"; url=argv[1]; } } dbus_send_to_self(connection,cmd.text(),url); return 1; } #endif long GMPlayerManager::onPlayNotify(FXObject*,FXSelector,void*){ update_cover_display(); if (!trackinfo.title.empty() && !trackinfo.artist.empty()) { display_track_notification(); if (lastfm) lastfm->nowplaying(trackinfo); } return 0; } long GMPlayerManager::onUpdTrackDisplay(FXObject*,FXSelector,void*){ update_track_display(); if (source) getTrackView()->showCurrent(); return 0; } long GMPlayerManager::onUpdEvents(FXObject*,FXSelector,void*){ handle_async_events(); application->addTimeout(this,GMPlayerManager::ID_HANDLE_EVENTS,TIME_MSEC(500)); return 0; } /* Stop Playback! */ long GMPlayerManager::onCmdSleepTimer(FXObject*,FXSelector,void*){ cmd_stop(); return 1; } #ifdef HAVE_DBUS long GMPlayerManager::onCmdSettingsDaemon(FXObject*,FXSelector,void*ptr){ const FXchar * cmd = (const FXchar*)ptr; if (comparecase(cmd,"play")==0) cmd_playpause(); else if (comparecase(cmd,"pause")==0) cmd_playpause(); else if (comparecase(cmd,"stop")==0) cmd_stop(); else if (comparecase(cmd,"previous")==0) cmd_prev(); else if (comparecase(cmd,"next")==0) cmd_next(); else { GM_DEBUG_PRINT("Unknown or unhandled key press: %s\n",cmd); } return 1; } #endif long GMPlayerManager::onDDEMessage(FXObject*,FXSelector,void*){ FXString cmd; FXchar buffer[1024]; int nread=fifo.readBlock(buffer,1024); if (nread>0) { cmd=FXString(buffer,nread); cmd.trim(); if (cmd=="--previous") cmd_prev(); else if (cmd=="--play") cmd_play(); else if (cmd=="--play-pause") cmd_playpause(); else if (cmd=="--pause") cmd_pause(); else if (cmd=="--next") cmd_next(); else if (cmd=="--stop") cmd_stop(); else if (cmd=="--toggle-shown") cmd_toggle_shown(); else if (cmd=="--now-playing") display_track_notification(); else if (cmd=="--raise") { if (mainwindow->shown()) mainwindow->raise(); } else if (cmd.length() && cmd[0]!='-') { open(cmd); } } return 1; } GMPlayerManager * GMPlayerManager::myself = NULL; GMPlayerManager* GMPlayerManager::instance() { return myself; } /// Constructor GMPlayerManager::GMPlayerManager() : count_track_remaining(0), #ifdef HAVE_DBUS sessionbus(NULL), systembus(NULL), notifydaemon(NULL), mpris(NULL), gsd(NULL), #endif application(NULL), mainwindow(NULL), player(NULL), trayicon(NULL), lastfm(NULL), source(NULL) { FXASSERT(myself==NULL); myself=this; database=NULL; } /// Destructor GMPlayerManager::~GMPlayerManager() { /// Remove Signal Handlers #ifndef DEBUG application->removeSignal(SIGINT); application->removeSignal(SIGQUIT); application->removeSignal(SIGTERM); application->removeSignal(SIGHUP); application->removeSignal(SIGPIPE); #endif application->removeSignal(SIGCHLD); /// Cleanup fifo crap if (fifo.isOpen()) fifo.close(); if (!fifofilename.empty()) FXFile::remove(fifofilename); delete lastfm; /// Delete Sources for (FXint i=0;itrackview; } GMSourceView * GMPlayerManager::getSourceView() const { return mainwindow->sourceview; } FXint GMPlayerManager::init_fifo(int& argc,char** argv){ FXString fifodir = FXSystem::getHomeDirectory() + PATHSEPSTRING + ".goggles"; FXStat info; if ( (!FXStat::exists(fifodir) && !FXDir::create(fifodir) ) || !FXStat::isDirectory(fifodir) ) { FXMessageBox::error(application,MBOX_OK,"Goggles Music Manager",fxtrformat("Unable to create directory %s\n"),fifodir.text()); return FIFO_STATUS_ERROR; } fifofilename = fifodir + PATHSEPSTRING + "gmm.dde"; /// Find existing fifo if (FXStat::statFile(fifofilename,info)) { /// File exists, but it's not a fifo... try removing it if (!info.isFifo() && !FXFile::remove(fifofilename)) { fifofilename=FXString::null; return FIFO_STATUS_ERROR; } if (fifo.open(fifofilename,FXIO::WriteOnly|FXIO::NonBlocking)){ FXString commandline; for (FXint i=1;iinitPlaylists(sources); sources.append(new GMStreamSource(database)); return true; } void GMPlayerManager::init_window(FXbool wizard) { const FXint argc = application->getArgc(); const FXchar *const * argv = application->getArgv(); /// Create Main Window mainwindow = new GMWindow(application,this,ID_WINDOW); mainwindow->create(); // Register Global Hotkeys register_global_hotkeys(); /// Handle interrupt to save stuff nicely #ifndef DEBUG application->addSignal(SIGINT,mainwindow,GMWindow::ID_QUIT); application->addSignal(SIGQUIT,mainwindow,GMWindow::ID_QUIT); application->addSignal(SIGTERM,mainwindow,GMWindow::ID_QUIT); application->addSignal(SIGHUP,mainwindow,GMWindow::ID_QUIT); application->addSignal(SIGPIPE,mainwindow,GMWindow::ID_QUIT); #endif /// Create Tooltip Window FXToolTip * tooltip = new FXToolTip(application); tooltip->create(); ewmh_change_window_type(tooltip,WINDOWTYPE_TOOLTIP); GMDatabaseSource * dbsrc = dynamic_cast(sources[0]); if (dbsrc->getNumTracks()==0 && dbsrc->getNumStreams()==0 && wizard) { cleanSourceSettings(); mainwindow->init(SHOW_WIZARD); } else { FXbool start_as_tray=false; for(FXint i=1;iinit(SHOW_TRAY); else mainwindow->init(SHOW_NORMAL); } application->addTimeout(this,GMPlayerManager::ID_HANDLE_EVENTS,TIME_MSEC(500)); } static FXString get_cmdline_url(int& argc,char** argv) { FXString url; for (FXint i=1;iinit(argc,argv); application->create(); /// Keep track of child processes application->addSignal(SIGCHLD,this,GMPlayerManager::ID_CHILD); /// Give warning when PNG is not compiled in... if (FXPNGIcon::supported==false) { FXMessageBox::warning(application,MBOX_OK,"Goggles Music Manager", fxtr("For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system.")); } #ifdef HAVE_DBUS sessionbus=new GMDBus(); systembus=new GMDBus(); if (!sessionbus->open(DBUS_BUS_SESSION) || !sessionbus->connected()) { FXMessageBox::warning(application,MBOX_OK,"Goggles Music Manager",fxtr("Session bus not available. All features requiring dbus are disabled.")); delete sessionbus; sessionbus=NULL; } else { FXint result = dbus_bus_request_name(sessionbus->connection(),GOGGLESMM_DBUS_NAME,DBUS_NAME_FLAG_DO_NOT_QUEUE,NULL); switch(result) { case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: { if (!dbus_connection_register_object_path(sessionbus->connection(),"/org/fifthplanet/gogglesmm",&org_fifthplanet_gogglesmm,this)){ FXMessageBox::warning(application,MBOX_OK,"Goggles Music Manager",fxtr("A DBus error occurred. All features requiring sessionbus are disabled.")); delete sessionbus; sessionbus=NULL; } } break; case DBUS_REQUEST_NAME_REPLY_EXISTS: dbus_send_commands(sessionbus->connection(),argc,argv); return 0; break; default: FXMessageBox::warning(application,MBOX_OK,"Goggles Music Manager",fxtr("Session Bus not available. All features requiring sessionbus are disabled.")); delete sessionbus; sessionbus=NULL; break; } } /// Fallback to fifo method to check for existing instance if (sessionbus==NULL) { result = init_fifo(argc,argv); if (result==FIFO_STATUS_ERROR) return 1; else if (result==FIFO_STATUS_EXISTS) return 0; } if (!systembus->open(DBUS_BUS_SYSTEM) || !systembus->connected()) { delete systembus; systembus=NULL; } if (systembus && !dbus_connection_add_filter(systembus->connection(),dbus_systembus_filter,this,NULL)){ delete systembus; systembus=NULL; } if (systembus) { DBusError error; dbus_error_init(&error); dbus_bus_add_match(systembus->connection(),"type='signal',path='/org/freedesktop/NetworkManager',interface='org.freedesktop.NetworkManager',member='StateChanged'",&error); if (dbus_error_is_set(&error)) { dbus_error_free(&error); delete systembus; systembus=NULL; } } if (systembus) { DBusError error; dbus_error_init(&error); dbus_bus_add_match(systembus->connection(),"type='signal',path='/org/freedesktop/NetworkManager',interface='org.freedesktop.NetworkManager',member='StateChange'",&error); if (dbus_error_is_set(&error)) { dbus_error_free(&error); delete systembus; systembus=NULL; } } #else result = init_fifo(argc,argv); if (result==FIFO_STATUS_ERROR) return 1; else if (result==FIFO_STATUS_EXISTS) return 0; #endif /// Open Database and initialize all sources. if (!init_sources()) return false; /// Everything opened succesfully... now create the GUI player = new GMPlayer(argc,argv); /// Load Application Preferences preferences.load(application->reg()); /// Check for overrides on the command line preferences.parseCommandLine(argc,argv); /// Open Audio Device if needed. if (preferences.play_open_device_on_startup) { if (!player->initialize()) { FXString errormsg; player->getErrorMessage(errormsg); FXMessageBox::error(application,MBOX_OK,fxtr("Audio Device Error"),"%s",errormsg.text()); } } /// Receive events from fifo if (fifo.isOpen()) { #if FOXVERSION < FXVERSION(1,7,0) application->addInput(fifo.handle(),INPUT_READ,this,GMPlayerManager::ID_DDE_MESSAGE); #else application->addInput(this,GMPlayerManager::ID_DDE_MESSAGE,fifo.handle(),INPUT_READ); #endif } FXString url = get_cmdline_url(argc,argv); /// Show user interface init_window(url.empty()); #ifdef HAVE_DBUS if (sessionbus) { /// Integrate Dbus into FOX Event Loop GMDBus::initEventLoop(); } #endif lastfm = new GMAudioScrobbler(this,ID_SCROBBLER); #ifdef HAVE_DBUS if (sessionbus) { notifydaemon = new GMNotifyDaemon(sessionbus); mpris = new GMMediaPlayerService(sessionbus); gsd = new GMSettingsDaemon(sessionbus,this,ID_GNOME_SETTINGS_DAEMON); gsd->GrabMediaPlayerKeys("gogglesmm"); notifydaemon->init(); } #endif /// Open url from command line if (!url.empty()) open(url); #ifndef HAVE_DBUS update_tray_icon(); #endif /// Run the application return application->run(); } void GMPlayerManager::removeSource(GMSource *src) { sources.remove(src); } void GMPlayerManager::exit() { /// Stop Playing stop(); /// Close and Save Settings player->close(); #ifdef HAVE_DBUS if (sessionbus) { DBusMessage * msg = dbus_message_new_signal(GOGGLESMM_DBUS_PATH,GOGGLESMM_DBUS_INTERFACE,"quit"); if (msg) { dbus_connection_send(sessionbus->connection(),msg,NULL); dbus_message_unref(msg); } } #endif application->removeTimeout(this,GMPlayerManager::ID_HANDLE_EVENTS); application->removeTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY); application->removeTimeout(this,GMPlayerManager::ID_SLEEP_TIMER); application->removeTimeout(this,GMPlayerManager::ID_PLAY_NOTIFY); application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); preferences.save(application->reg()); if (lastfm) lastfm->shutdown(); #ifdef HAVE_DBUS if (sessionbus) { dbus_connection_unregister_object_path(sessionbus->connection(),"/org/fifthplanet/gogglesmm"); gsd->ReleaseMediaPlayerKeys("gogglesmm"); delete gsd; gsd=NULL; if (notifydaemon) delete notifydaemon; if (mpris) delete mpris; } if (systembus) { dbus_connection_remove_filter(systembus->connection(),dbus_systembus_filter,this); } #endif application->exit(0); } void GMPlayerManager::update_tray_icon() { if (!preferences.gui_tray_icon_disabled) { if (trayicon && !preferences.gui_tray_icon) { delete trayicon; trayicon=NULL; } else if (!trayicon && preferences.gui_tray_icon) { trayicon = new GMTrayIcon(application); trayicon->create(); if (!trayicon->dock()) { preferences.gui_tray_icon=false; delete trayicon; trayicon=NULL; } } } } FXbool GMPlayerManager::init_database(GMTrackDatabase *& db, const FXString & filename){ FXString dir = FXSystem::getHomeDirectory() + PATHSEPSTRING + ".goggles"; FXString databasefilename = dir + PATHSEPSTRING + filename; if (FXStat::exists(dir)) { if (!FXStat::isDirectory(dir)) return FALSE; } else { if (!FXDir::create(dir)) return FALSE; } if (!FXStat::isWritable(dir) || !FXStat::isReadable(dir)) return FALSE; if (FXStat::exists(databasefilename) && (!FXStat::isWritable(databasefilename) || !FXStat::isReadable(databasefilename))) return FALSE; if (!db) { db = new GMTrackDatabase(); } /// Init Database if (!db->init(databasefilename,true)) { return false; } return TRUE; } FXbool GMPlayerManager::hasSourceWithKey(const char * key) const{ for (FXint i=0;isettingKey()==key) return true; } return false; } void GMPlayerManager::cleanSourceSettings() { FXint s; FXStringList keys; for (s=application->reg().first();sreg().size();s=application->reg().next(s)){ if (comparecase(application->reg().key(s),"database",8)==0){ if (!hasSourceWithKey(application->reg().key(s))) { keys.append(application->reg().key(s)); } } } for (s=0;sreg().deleteSection(keys[s].text()); } } void GMPlayerManager::removePlayListSources(){ GMSource * src; for (FXint i=sources.no()-1;i>=0;i--){ src=sources[i]; if (src->getType()==SOURCE_DATABASE_PLAYLIST) { FXApp::instance()->reg().deleteSection(sources[i]->settingKey().text()); sources.erase(i); delete src; } } } void GMPlayerManager::download(const FXString & filename){ FXString status = "Downloading " + filename + " ..."; GMPlayerManager::instance()->setStatus(status); GMFetch::download(filename); } FXbool GMPlayerManager::play(const FXString & filename) { FXString errormsg; /// Open Filename if (!player->open(filename)){ /// Reset Source if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } /// Reset Track Display reset_track_display(); /// Show error dialog once we return to event loop application->addChore(this,ID_PLAYER_ERROR); /// Close if (preferences.play_close_stream) player->close(); return false; } /// Start Playback if (!player->play()) { /// Reset Source if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } /// Reset Track Display reset_track_display(); /// Show error dialog once we return to event loop application->addChore(this,ID_PLAYER_ERROR); /// Close if (preferences.play_close_stream) player->close(); return false; } return true; } FXbool GMPlayerManager::play(const FXStringList & list) { FXString errormsg; for (FXint i=0;iopen(list[i])){ continue; } /// Start Playback if (!player->play()) { continue; } return true; } /// Show error dialog once we return to event loop application->addChore(this,ID_PLAYER_ERROR); /// Reset Source if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } /// Reset Track Display reset_track_display(); /// Close if (preferences.play_close_stream) player->close(); return false; } void GMPlayerManager::open(const FXString & uri) { /// Make sure we have something if (uri.empty()) return; /// Get a uri we can process FXString filename = gm_parse_uri(uri); /// Stop fetching GMFetch::cancel_and_wait(); /// Reset track info trackinfoset=false; /// Stop Current Playback player->stop(); /// Remove any pending track display updates application->removeTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY); /// Remove Current Timeout if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } /// Check for pls or m3u, since xine cannot handle that FXbool local = gm_is_local_file(filename); if (!local) { trackinfo.mrl = filename; download(filename); return; } if (local) { FXint id; if (sources[0]->hasTrack(filename,id)) { sources[0]->setCurrentTrack(id); source=sources[0]; getTrackView()->handle(this,FXSEL(SEL_COMMAND,GMTrackView::ID_SHOW_CURRENT),NULL); trackinfoset = source->getTrack(trackinfo); } else { /// Reset Active Track trackinfoset = trackinfo.loadTag(filename); getTrackView()->mark(-1); } } else { /// Reset Active Track getTrackView()->mark(-1); } /// Play File if (play(filename) && local) { update_track_display(); } } void GMPlayerManager::play() { FXString filename; FXint track; /// Stop fetching GMFetch::cancel_and_wait(); /// Reset trackinfoset trackinfoset=false; /// Stop Current Playback player->stop(); /// Remove any pending track display updates application->removeTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY); /// Remove Current Timeout if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } track = getTrackView()->getCurrent(); if (track==-1) return; /// Mark Track source = getTrackView()->getSource(); getTrackView()->mark(track); /// Get the track info trackinfoset = source->getTrack(trackinfo); /// Check for pls or m3u, since xine cannot handle that FXbool local = gm_is_local_file(trackinfo.mrl); if (!local) { download(trackinfo.mrl); return; } if (play(trackinfo.mrl)){ if (local) update_track_display(); else reset_track_display(); } } void GMPlayerManager::stop(FXbool force_close) { /// Wait for download to finish. GMFetch::cancel_and_wait(); /// Reset Source if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } if (preferences.play_close_stream || force_close){ player->stop(); player->close(); } else { player->stop(); } /// Reset Track Display reset_track_display(); } namespace FX { extern FXlong fxgetticks(); } //static FXint next_track; void GMPlayerManager::next() { FXint track; GMFetch::cancel_and_wait(); player->stop(); /// Remove any pending track display updates application->removeTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY); /// Remove Current Timeout if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } track = getTrackView()->getNext(true); if (track==-1) return; /// Mark Track source = getTrackView()->getSource(); getTrackView()->mark(track); /// Get the Track info trackinfoset = source->getTrack(trackinfo); /// Check for pls or m3u, since xine cannot handle that FXbool local = gm_is_local_file(trackinfo.mrl); if (!local) { download(trackinfo.mrl); return; } if (play(trackinfo.mrl) && gm_is_local_file(trackinfo.mrl)) update_track_display(); } void GMPlayerManager::prev() { FXString filename; FXint track; GMFetch::cancel_and_wait(); /// Stop Current Playback player->stop(); /// Remove any pending track display updates application->removeTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY); /// Remove Current Timeout if (source) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->resetCurrent(); source=NULL; } track = getTrackView()->getPrevious(); if (track==-1) return; /// Mark Track source = getTrackView()->getSource(); getTrackView()->mark(track); /// Get Track Information trackinfoset = source->getTrack(trackinfo); /// Check for pls or m3u, since xine cannot handle that FXbool local = gm_is_local_file(trackinfo.mrl); if (!local) { download(trackinfo.mrl); return; } if (play(trackinfo.mrl) && gm_is_local_file(trackinfo.mrl)) update_track_display(); } void GMPlayerManager::seek(FXint pos) { /// Remove Current Timeout application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); player->play(pos); /// Prevent jumping of time slider application->addTimeout(this,GMPlayerManager::ID_HANDLE_EVENTS,TIME_MSEC(500)); } void GMPlayerManager::pause() { if (preferences.play_pause_close_device){ player->pause(); player->close_device(); } else { player->pause(); } count_track_remaining = application->remainingTimeout(source,GMSource::ID_TRACK_PLAYED); application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); } void GMPlayerManager::unpause() { player->unpause(); if (player->getVolume()==0) player->setVolume(50); if (count_track_remaining>0 && source){ application->addTimeout(source,GMSource::ID_TRACK_PLAYED,count_track_remaining); } count_track_remaining=0; mainwindow->update_volume_display(player->getVolume()); } FXbool GMPlayerManager::playlist_empty() { if (getTrackView()->hasTracks()) return false; if (preferences.play_repeat!=REPEAT_OFF) return false; if (getTrackView()->getNext()!=-1) return false; return true; } void GMPlayerManager::notify_playback_finished() { FXString errormsg; FXString filename; FXint track; FXint remaining = player->remaining(); /// Can we just start playback without user interaction if (!getTrackView()->getSource()->autoPlay()) { /// Reset Source if (source) { source->resetCurrent(); source=NULL; } reset_track_display(); return; } if (source) { source->resetCurrent(); source=NULL; } if (preferences.play_repeat==REPEAT_TRACK) track = getTrackView()->getCurrent(); else track = getTrackView()->getNext(); if (track==-1) { reset_track_display(); return; } getTrackView()->mark(track,(remaining<=0)); source = getTrackView()->getSource(); trackinfoset = source->getTrack(trackinfo); if (play(trackinfo.mrl)) { if (remaining>0) application->addTimeout(this,GMPlayerManager::ID_UPDATE_TRACK_DISPLAY,TIME_SEC(remaining),(void*)(FXival)track); else update_track_display(); } } FXbool GMPlayerManager::playing() const { return player->playing() || GMFetch::busy() ; } FXbool GMPlayerManager::audio_device_opened() const{ return player->opened(); } FXint GMPlayerManager::current_position() const { return player->getPosition(); } void GMPlayerManager::reset_track_display() { FXTRACE((51,"GMPlayerManager::reset_track_display()\n")); /// Reset Main Window mainwindow->reset(); if (trayicon) trayicon->reset(); /// Reset Active Track getTrackView()->mark(-1); /// Remove Notify application->removeTimeout(this,ID_PLAY_NOTIFY); #ifdef HAVE_DBUS if (notifydaemon && preferences.dbus_notify_daemon) notifydaemon->close(); #endif /// Schedule a GUI update application->refresh(); } void GMPlayerManager::setStatus(const FXString & text){ mainwindow->statusbar->getStatusLine()->setNormalText(text); } void GMPlayerManager::update_track_display(FXbool notify) { FXTRACE((51,"GMPlayerManager::update_track_display()\n")); /// If track information is not set, we need to get the latest from the player. if (!trackinfoset && player->playing()) { player->getTrackInformation(trackinfo); if (source) source->setTrack(trackinfo); } if (source) { FXint time = (FXint) (((double)trackinfo.time) * 0.80); if (time <= 5) { application->removeTimeout(source,GMSource::ID_TRACK_PLAYED); source->handle(this,FXSEL(SEL_TIMEOUT,GMSource::ID_TRACK_PLAYED),NULL); } else { count_track_remaining=0; application->addTimeout(source,GMSource::ID_TRACK_PLAYED,TIME_SEC(time)); } } if (trayicon && player->playing()) { trayicon->display(trackinfo); } mainwindow->display(trackinfo); /// Make sure Volume Level is up 2 date mainwindow->update_volume_display(player->getVolume()); update_replay_gain(); if (notify) application->addTimeout(this,ID_PLAY_NOTIFY,TIME_MSEC(500)); } void GMPlayerManager::update_replay_gain() { switch(preferences.play_replaygain){ case REPLAYGAIN_OFF : player->setReplayGain(NAN,NAN); break; case REPLAYGAIN_TRACK : player->setReplayGain(trackinfo.track_gain,trackinfo.track_peak); break; case REPLAYGAIN_ALBUM : player->setReplayGain(trackinfo.album_gain,trackinfo.album_peak); break; } } void GMPlayerManager::handle_async_events() { /// Get Events from player player->handle_async_events(); /// Mark Time mainwindow->update_elapsed_time(player->getHours(),player->getMinutes(),player->getSeconds(),player->getPosition(),player->playing(),player->seekable()); } FXint GMPlayerManager::volume() const{ return player->getVolume(); } void GMPlayerManager::volume(FXint l) { player->setVolume(l); } FXbool GMPlayerManager::can_stop() const { if (player->playing() || GMFetch::busy() ) return true; return false; } FXbool GMPlayerManager::can_play() const { if (!player->playing() && getTrackView()->hasTracks() && !GMFetch::busy()) return true; return false; } FXbool GMPlayerManager::can_pause() const { if (player->playing() && !player->pausing()) return true; return false; } FXbool GMPlayerManager::can_unpause() const { if (player->playing() && player->pausing()) return true; return false; } FXbool GMPlayerManager::can_next() const { if (player->playing() && !player->pausing() && getTrackView()->getNumTracks()>1) return true; return false; } FXbool GMPlayerManager::can_prev() const { if (player->playing() && !player->pausing() && getTrackView()->getNumTracks()>1) return true; return false; } #if FOXVERSION < FXVERSION(1,7,0) void GMPlayerManager::setSleepTimer(FXuint ms) { if (ms==0) application->removeTimeout(this,GMPlayerManager::ID_SLEEP_TIMER); else application->addTimeout(this,GMPlayerManager::ID_SLEEP_TIMER,ms); } #else void GMPlayerManager::setSleepTimer(FXlong ns) { if (ns==0) application->removeTimeout(this,GMPlayerManager::ID_SLEEP_TIMER); else application->addTimeout(this,GMPlayerManager::ID_SLEEP_TIMER,ns); } #endif FXbool GMPlayerManager::hasSleepTimer() { return application->hasTimeout(this,GMPlayerManager::ID_SLEEP_TIMER); } void GMPlayerManager::show_message(const FXchar * title,const FXchar * msg){ if (application->getActiveWindow() && application->getActiveWindow()->shown()) { FXMessageBox::error(application->getActiveWindow(),MBOX_OK,title,"%s",msg); } else { if (mainwindow && mainwindow->shown()) FXMessageBox::error(mainwindow,MBOX_OK,title,"%s",msg); else if (mainwindow->getRemote()) FXMessageBox::error(mainwindow->getRemote(),MBOX_OK,title,"%s",msg); else FXMessageBox::error(application,MBOX_OK,title,"%s",msg); } } long GMPlayerManager::onCmdShowManager(FXObject*,FXSelector,void*){ mainwindow->hideRemote(); return 1; } long GMPlayerManager::onCmdCloseWindow(FXObject*sender,FXSelector,void*){ FXWindow * window = reinterpret_cast(sender); if (getPreferences().gui_hide_player_when_close && trayicon) { window->hide(); } else { getMainWindow()->handle(this,FXSEL(SEL_COMMAND,GMWindow::ID_QUIT),NULL); } return 1; } long GMPlayerManager::onCmdChild(FXObject*,FXSelector,void*){ FXint pid; FXint status; while(1) { pid = waitpid(-1,&status,WNOHANG); if (pid>0) { continue; } break; } return 1; } long GMPlayerManager::onScrobblerError(FXObject*,FXSelector,void*ptr){ show_message(fxtr("Last.FM Error"),(const FXchar*)ptr); return 1; } long GMPlayerManager::onScrobblerOpen(FXObject*,FXSelector,void*ptr){ gm_open_browser((const FXchar*)ptr); return 1; } long GMPlayerManager::onPlayerError(FXObject*,FXSelector,void*){ FXString errormsg; player->getErrorMessage(errormsg); show_message(fxtr("Playback Error"),errormsg.text()); return 1; } long GMPlayerManager::onCmdDownloadComplete(FXObject*,FXSelector,void*ptr){ GMFetchResponse * response = NULL; if (ptr) response = *((GMFetchResponse**)ptr); if (response) { if (response->url == trackinfo.mrl ) { FXStringList list; if ((response->content_type.find("audio/mpegurl")!=-1 || response->content_type.find("audio/x-mpegurl")!=-1) && response->data.length()){ gm_parse_m3u(response->data,list); } else if ((response->content_type.find("application/pls+xml")!=-1 || response->content_type.find("audio/x-scpls")!=-1) && response->data.length()) { gm_parse_pls(response->data,list); } else { list.append(response->url); } play(list); } else { reset_track_display(); } delete response; } else { reset_track_display(); } return 1; } long GMPlayerManager::onCmdEqualizer(FXObject *,FXSelector,void*){ GMEQDialog * eqdialog = GMEQDialog::instance(); if (eqdialog==NULL) { eqdialog = new GMEQDialog(mainwindow); eqdialog->create(); } eqdialog->show(); return 1; } // Perhaps should do something else... static int xregisterhotkeys(Display* dpy,XErrorEvent* eev){ char buf[256]; if(eev->error_code==BadAccess && eev->request_code==33) return 0; // A BadWindow due to X_SendEvent is likely due to XDND if(eev->error_code==BadWindow && eev->request_code==25) return 0; // WM_TAKE_FOCUS causes sporadic errors for X_SetInputFocus if(eev->request_code==42) return 0; // Get error codes XGetErrorText(dpy,eev->error_code,buf,sizeof(buf)); // Print out meaningful warning fxwarning("GMM X Error: code %d major %d minor %d: %s.\n",eev->error_code,eev->request_code,eev->minor_code,buf); return 1; } void GMPlayerManager::register_global_hotkeys() { Window root = application->getRootWindow()->id(); Display * display = (Display*) application->getDisplay(); KeyCode keycode; XErrorHandler previous = XSetErrorHandler(xregisterhotkeys); /// Only register hotkeys on the rootwindow. #ifdef XF86XK_AudioPlay keycode = XKeysymToKeycode(display,XF86XK_AudioPlay); if (keycode) XGrabKey(display,keycode,AnyModifier,root,False,GrabModeAsync,GrabModeAsync); #endif #ifdef XF86XK_AudioPause keycode = XKeysymToKeycode(display,XF86XK_AudioPause); if (keycode) XGrabKey(display,keycode,AnyModifier,root,False,GrabModeAsync,GrabModeAsync); #endif #ifdef XF86XK_AudioStop keycode = XKeysymToKeycode(display,XF86XK_AudioStop); if (keycode) XGrabKey(display,keycode,AnyModifier,root,False,GrabModeAsync,GrabModeAsync); #endif #ifdef XF86XK_AudioNext keycode = XKeysymToKeycode(display,XF86XK_AudioNext); if (keycode) XGrabKey(display,keycode,AnyModifier,root,False,GrabModeAsync,GrabModeAsync); #endif #ifdef XF86XK_AudioPrev keycode = XKeysymToKeycode(display,XF86XK_AudioPrev); if (keycode) XGrabKey(display,keycode,AnyModifier,root,False,GrabModeAsync,GrabModeAsync); #endif XSync (display,False); XSetErrorHandler(previous); } FXbool GMPlayerManager::handle_global_hotkeys(FXuint code) { switch(code) { #ifdef XF86XK_AudioPlay case XF86XK_AudioPlay : cmd_playpause(); break; #endif #ifdef XF86XK_AudioPause case XF86XK_AudioPause : cmd_playpause(); break; #endif #ifdef XF86XK_AudioStop case XF86XK_AudioStop : cmd_stop(); break; #endif #ifdef XF86XK_AudioPrev case XF86XK_AudioPrev : cmd_prev(); break; #endif #ifdef XF86XK_AudioNext case XF86XK_AudioNext : cmd_next(); break; #endif default : return false; break; } return true; } void GMPlayerManager::update_cover_display() { if (preferences.gui_show_playing_albumcover && gm_is_local_file(trackinfo.mrl)) mainwindow->loadCover(trackinfo.mrl); } FXint GMPlayerManager::createPlaylist(const FXString & name) { FXint playlist; database->insertPlaylist(name,playlist); insertSource(new GMPlayListSource(database,playlist)); getSourceView()->refresh(); return playlist; } GMDatabaseSource * GMPlayerManager::getDatabaseSource() const { return dynamic_cast(sources[0]); } void GMPlayerManager::display_track_notification() { #ifdef HAVE_DBUS if (sessionbus && !trackinfo.title.empty() && !trackinfo.artist.empty()) { if (notifydaemon && preferences.dbus_notify_daemon) { FXString body = GMStringFormat(fxtrformat("%s\n%s (%d)"),trackinfo.artist.text(),trackinfo.album.text(),trackinfo.year); /// Dirty Hack. According to the spec, we shouldn't have to do this, /// but try finding a notification daemon that actually implements it... /// http://www.galago-project.org/specs/notification/0.9/index.html body.substitute("&","&"); notifydaemon->notify(trackinfo.title.text(),body.text(),-1,mainwindow->getSmallCover()); } if (mpris) mpris->notify_track_change(trackinfo); } #endif } void GMPlayerManager::cmd_play(){ if (can_unpause()) unpause(); else if (can_play()) play(); } void GMPlayerManager::cmd_playpause(){ if (can_pause()) pause(); else if (can_unpause()) unpause(); else if (can_play()) play(); } void GMPlayerManager::cmd_pause(){ if (can_pause()) pause(); else if (can_unpause()) unpause(); } void GMPlayerManager::cmd_stop(){ if (can_stop()) stop(); } void GMPlayerManager::cmd_next(){ if (can_next()) next(); } void GMPlayerManager::cmd_prev(){ if (can_prev()) prev(); } void GMPlayerManager::cmd_toggle_shown(){ getMainWindow()->toggleShown(); } gogglesmm-0.12.7/src/GMImportDialog.h0000644000175000001440000000775511526346217016110 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMIMPORTDIALOG_H #define GMIMPORTDIALOG_H class GMFileSelector; class GMDirSelector; enum { IMPORT_FROMPASTE = 0x0, IMPORT_FROMFILE = 0x1, IMPORT_FROMDIR = 0x2, IMPORT_SYNC = 0x4, IMPORT_PLAYLIST = 0x8 }; class GMFileDialog : public FXFileDialog { FXDECLARE(FXFileDialog) protected: GMFileDialog(){} private: GMFileDialog(const GMFileDialog&); GMFileDialog &operator=(const GMFileDialog&); public: GMFileDialog(FXWindow* owner,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=500,FXint h=300); GMFileDialog(FXApp* a,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=500,FXint h=300); }; class GMExportDialog : public GMFileDialog { FXDECLARE(GMExportDialog) protected: GMCheckButton * check_relative; protected: GMExportDialog(){} private: GMExportDialog(const GMExportDialog&); GMExportDialog &operator=(const GMExportDialog&); public: GMExportDialog(FXWindow* owner,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=500,FXint h=300); GMExportDialog(FXApp* a,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=500,FXint h=300); void setRelativePath(FXbool b) { check_relative->setCheck(b); } FXbool getRelativePath() const { return check_relative->getCheck(); } }; class GMImportDialog : public FXDialogBox { FXDECLARE(GMImportDialog) protected: FXuint mode; protected: FXDataTarget target_track_from_filelist; FXDataTarget target_replace_underscores; FXDataTarget target_default_field; FXDataTarget target_exclude_dir; FXDataTarget target_exclude_file; FXDataTarget target_parse_method; FXDataTarget target_filename_template; protected: GMFileSelector * fileselector; GMDirSelector * dirselector; FXGroupBox * template_grpbox; protected: FXFontPtr font_fixed; protected: GMImportDialog(){} void getDefaultSearchDirectory(FXString&); private: GMImportDialog(const GMImportDialog&); GMImportDialog &operator=(const GMImportDialog&); public: enum { ID_SYNC_NEW = FXDialogBox::ID_LAST, ID_SYNC_REMOVE_MISSING, ID_SYNC_UPDATE, ID_SYNC_UPDATE_ALL, ID_SYNC_UPDATE_MODIFIED, ID_SYNC_REMOVE_ALL, ID_PARSE_METHOD }; public: long onCmdSync(FXObject*,FXSelector,void*); long onUpdSync(FXObject*,FXSelector,void*); long onCmdAccept(FXObject*,FXSelector,void*); long onUpdAccept(FXObject*,FXSelector,void*); long onCmdParseMethod(FXObject*,FXSelector,void*); public: GMImportDialog(FXWindow * p,FXuint mode=IMPORT_FROMDIR); void getSelectedFiles(FXStringList & files); FXString getFilename() const; }; #endif gogglesmm-0.12.7/src/mpris_root.xml0000644000175000001440000000110211435112736016010 0ustar sxjusers gogglesmm-0.12.7/src/GMTrayIcon.h0000644000175000001440000000502111550640745015226 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTRAYICON_H #define GMTRAYICON_H class GMTrayIcon : public GMPlug { FXDECLARE(GMTrayIcon) protected: FXID xtraywindow; FXID xtrayopcode; FXID xtrayorientation; FXID xtrayxfceorientation; FXID xtrayvisual; protected: FXIcon * icon; FXbool opaque; FXString tip; private: GMTrayIcon(const GMTrayIcon*); GMTrayIcon& operator=(const GMTrayIcon&); protected: GMTrayIcon(); FXbool findSystemTray(); void requestDock(); FXuint getTrayOrientation(); FXuint getTrayVisual(); public: long onPaint(FXObject*,FXSelector,void*); long onConfigure(FXObject*,FXSelector,void*); long onLeftBtnPress(FXObject*,FXSelector,void*); long onMiddleBtnPress(FXObject*,FXSelector,void*); long onRightBtnRelease(FXObject*,FXSelector,void*); long onMouseWheel(FXObject*,FXSelector,void*); long onQueryTip(FXObject*,FXSelector,void*); public: GMTrayIcon(FXApp * app); void setToolTip(const FXString & t) { tip = t; } void display(const GMTrack&); void reset(); virtual void create(); FXbool dock(); void updateIcon(); virtual ~GMTrayIcon(); }; #endif gogglesmm-0.12.7/src/GMIconTheme.h0000644000175000001440000001046211525430601015344 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMICONTHEME_H #define GMICONTHEME_H struct GMIconSet { FXString name; FXString dir; FXString small; FXString medium; FXString large; void load(FXStream & store); void save(FXStream & store); }; typedef FXArray GMIconSetList; class GMIconTheme { private: FXApp * app; private: GMIconSetList iconsets; FXStringList basedirs; FXint set; FXint smallsize; FXint mediumsize; FXint largesize; FXbool rsvg; protected: FXIcon * loadIcon(const FXString & filename); FXImage * loadImage(const FXString & filename); protected: void loadIcon(FXIconPtr & icon,const FXString &pathlist,FXint size,const char * value,const FXColor blend); void loadResource(FXIconPtr & icon,const unsigned char * data,const char * type); protected: FXbool load_cache(); void save_cache(); void build(); FXString get_svg_cache(); void clear_svg_cache(); public: FXIconPtr icon_applogo; FXIconPtr icon_applogo_small; public: FXIconPtr icon_play; FXIconPtr icon_pause; FXIconPtr icon_stop; FXIconPtr icon_next; FXIconPtr icon_prev; FXIconPtr icon_play_toolbar; FXIconPtr icon_pause_toolbar; FXIconPtr icon_stop_toolbar; FXIconPtr icon_next_toolbar; FXIconPtr icon_prev_toolbar; FXIconPtr icon_copy; FXIconPtr icon_cut; FXIconPtr icon_paste; FXIconPtr icon_exit; FXIconPtr icon_close; FXIconPtr icon_settings; FXIconPtr icon_import; FXIconPtr icon_importfile; FXIconPtr icon_delete; FXIconPtr icon_edit; FXIconPtr icon_undo; FXIconPtr icon_info; FXIconPtr icon_homepage; FXIconPtr icon_sort; FXIconPtr icon_columns; FXIconPtr icon_album; FXIconPtr icon_artist; FXIconPtr icon_genre; FXIconPtr icon_source_library; FXIconPtr icon_source_playlist; FXIconPtr icon_source_internetradio; FXIconPtr icon_playlist; FXIconPtr icon_audio_volume_high; FXIconPtr icon_audio_volume_medium; FXIconPtr icon_audio_volume_low; FXIconPtr icon_audio_volume_muted; FXIconPtr icon_export; FXIconPtr icon_find; FXIconPtr icon_sync; FXIconPtr icon_nocover; FXIconPtr icon_fullscreen; public: FXCursorPtr cursor_hand; private: static GMIconTheme * me; public: static GMIconTheme * instance(); public: GMIconTheme(FXApp * app); void loadSmall(FXIconPtr & icon,const char * value,const FXColor blend); void loadMedium(FXIconPtr & icon,const char * value,const FXColor blend); void loadLarge(FXIconPtr & icon,const char * value,const FXColor blend); FXImage * loadMedium(const char * value); FXint getSmallSize() const { return smallsize; } FXint getMediumSize() const { return mediumsize; } FXint getLargeSize() const { return largesize; } FXint getNumThemes() const; void setCurrentTheme(FXint i); FXint getCurrentTheme() const; FXString getThemeName(FXint i); void load(); ~GMIconTheme(); }; extern void gm_set_application_icon(FXWindow*); #endif gogglesmm-0.12.7/src/GMMediaPlayerService.cpp0000644000175000001440000003264611644106465017563 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2010-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMDBus.h" #include "GMSource.h" #include "GMWindow.h" #include #include "GMPlayer.h" #include "GMPlayerManager.h" #include "GMMediaPlayerService.h" #include "mpris_xml.h" static void gm_mpris_track_to_dict(DBusMessageIter * iter,const GMTrack & track) { DBusMessageIter array; dbus_message_iter_open_container(iter,DBUS_TYPE_ARRAY,"{sv}",&array); gm_dbus_dict_append_string(&array,"title",track.title); gm_dbus_dict_append_string(&array,"artist",track.artist); gm_dbus_dict_append_string(&array,"album",track.album); gm_dbus_dict_append_string(&array,"tracknumber",GMStringVal(track.no)); gm_dbus_dict_append_uint32(&array,"time",track.time); gm_dbus_dict_append_uint32(&array,"year",track.year); gm_dbus_dict_append_string(&array,"genre",track.genre); gm_dbus_dict_append_string(&array,"location",gm_make_url(track.mrl)); dbus_message_iter_close_container(iter,&array); } /* static void gm_dbus_dict_append_track(DBusMessageIter * iter,const FXchar * key,const GMTrack & track) { DBusMessageIter entry; DBusMessageIter variant; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&entry); dbus_message_iter_append_basic(&entry,DBUS_TYPE_STRING,&key); dbus_message_iter_open_container(&entry,DBUS_TYPE_VARIANT,"a{sv}",&variant); gm_mpris_track_to_dict(&variant,track); dbus_message_iter_close_container(&entry,&variant); dbus_message_iter_close_container(iter,&entry); } */ static const FXchar MPRIS_DBUS_NAME[]="org.mpris.gogglesmm"; static const FXchar MPRIS_DBUS_INTERFACE[]="org.freedesktop.MediaPlayer"; static const FXchar MPRIS_DBUS_PLAYER[]="/Player"; static const FXchar MPRIS_DBUS_ROOT[]="/"; static const FXchar MPRIS_DBUS_TRACKLIST[]="/TrackList"; static FXint mpris_get_caps(GMPlayerManager * p) { FXint caps=0; enum { MPRIS_CAPS_NONE = 0, MPRIS_CAPS_CAN_GO_NEXT = 1 << 0, MPRIS_CAPS_CAN_GO_PREV = 1 << 1, MPRIS_CAPS_CAN_PAUSE = 1 << 2, MPRIS_CAPS_CAN_PLAY = 1 << 3, MPRIS_CAPS_CAN_SEEK = 1 << 4, MPRIS_CAPS_CAN_PROVIDE_METADATA = 1 << 5, MPRIS_CAPS_CAN_HAS_TRACKLIST = 1 << 6 }; if (p->can_play() || p->can_unpause()) caps|=MPRIS_CAPS_CAN_PLAY; if (p->can_pause()) caps|=MPRIS_CAPS_CAN_PAUSE; if (p->can_prev()) caps|=MPRIS_CAPS_CAN_GO_PREV; if (p->can_next()) caps|=MPRIS_CAPS_CAN_GO_NEXT; caps|=MPRIS_CAPS_CAN_PROVIDE_METADATA; return caps; } static void gm_mpris_get_status(DBusMessageIter * iter,GMPlayerManager * p) { enum { MPRIS_STATUS_PLAYING = 0, MPRIS_STATUS_PAUSED = 1, MPRIS_STATUS_STOPPED = 2, }; FXint playstatus=0; FXint playmode=0; FXint playnext=0; FXint playrepeat=0; if (p->can_unpause()) playstatus=MPRIS_STATUS_PAUSED; else if (p->can_pause()) playstatus=MPRIS_STATUS_PLAYING; else playstatus=MPRIS_STATUS_STOPPED; DBusMessageIter str; dbus_message_iter_open_container(iter,DBUS_TYPE_STRUCT,NULL,&str); dbus_message_iter_append_basic(&str,DBUS_TYPE_INT32,&playstatus); dbus_message_iter_append_basic(&str,DBUS_TYPE_INT32,&playmode); dbus_message_iter_append_basic(&str,DBUS_TYPE_INT32,&playnext); dbus_message_iter_append_basic(&str,DBUS_TYPE_INT32,&playrepeat); dbus_message_iter_close_container(iter,&str); } FXIMPLEMENT(GMMediaPlayerService,FXObject,NULL,0) GMMediaPlayerService::GMMediaPlayerService(GMDBus * b) : bus(b),published(false){ memset(&root_vtable,0,sizeof(DBusObjectPathVTable)); root_vtable.message_function=&root_filter; memset(&player_vtable,0,sizeof(DBusObjectPathVTable)); player_vtable.message_function=&player_filter; memset(&tracklist_vtable,0,sizeof(DBusObjectPathVTable)); tracklist_vtable.message_function=&tracklist_filter; int result = dbus_bus_request_name(bus->connection(),MPRIS_DBUS_NAME,DBUS_NAME_FLAG_DO_NOT_QUEUE,NULL); if (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ) { dbus_connection_register_object_path(bus->connection(),MPRIS_DBUS_ROOT,&root_vtable,this); dbus_connection_register_object_path(bus->connection(),MPRIS_DBUS_PLAYER,&player_vtable,this); dbus_connection_register_object_path(bus->connection(),MPRIS_DBUS_TRACKLIST,&tracklist_vtable,this); published=true; } } GMMediaPlayerService::~GMMediaPlayerService(){ if (published) { dbus_connection_unregister_object_path(bus->connection(),MPRIS_DBUS_ROOT); dbus_connection_unregister_object_path(bus->connection(),MPRIS_DBUS_PLAYER); dbus_connection_unregister_object_path(bus->connection(),MPRIS_DBUS_TRACKLIST); published=false; dbus_bus_release_name(bus->connection(),MPRIS_DBUS_NAME,NULL); } } void GMMediaPlayerService::notify_track_change(const GMTrack & info) { if (published) { DBusMessage * msg = dbus_message_new_signal(MPRIS_DBUS_PLAYER,MPRIS_DBUS_INTERFACE,"TrackChange"); if (msg) { DBusMessageIter iter; dbus_message_iter_init_append(msg,&iter); gm_mpris_track_to_dict(&iter,info); bus->send(msg); } } } void GMMediaPlayerService::notify_status_change() { DBusMessage * msg = dbus_message_new_signal(MPRIS_DBUS_PLAYER,MPRIS_DBUS_INTERFACE,"StatusChange"); if (msg) { DBusMessageIter iter; dbus_message_iter_init_append(msg,&iter); gm_mpris_get_status(&iter,GMPlayerManager::instance()); bus->send(msg); } } void GMMediaPlayerService::notify_caps_change() { if (published) { DBusMessage * msg = dbus_message_new_signal(MPRIS_DBUS_PLAYER,MPRIS_DBUS_INTERFACE,"CapsChange"); if (msg) { FXint caps = mpris_get_caps(GMPlayerManager::instance()); dbus_message_append_args(msg,DBUS_TYPE_INT32,&caps,DBUS_TYPE_INVALID); bus->send(msg); } } } DBusHandlerResult GMMediaPlayerService::root_filter(DBusConnection *connection,DBusMessage * msg,void * /*ptr*/){ DEBUG_DBUS_MESSAGE(msg); DBusMessage * reply=NULL; FXuint serial; GMPlayerManager * p = GMPlayerManager::instance(); if (dbus_message_is_method_call(msg,"org.freedesktop.DBus.Introspectable","Introspect")){ FXString xml(mpris_root_xml); char ** children=NULL; if (dbus_connection_list_registered(connection,"/",&children)) { for (FXint i=0;children[i]!=NULL;i++) { xml+=GMStringFormat("\t\n",children[i]); } dbus_free_string_array(children); } xml+=""; return gm_dbus_reply_string(connection,msg,xml.text()); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Identity")) { return gm_dbus_reply_string(connection,msg,"Goggles Music Manager"); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"MprisVersion")) { reply = dbus_message_new_method_return(msg); if (reply) { FXushort major=1,minor=0; DBusMessageIter iter; DBusMessageIter str; dbus_message_iter_init_append(reply,&iter); dbus_message_iter_open_container(&iter,DBUS_TYPE_STRUCT,NULL,&str); dbus_message_iter_append_basic(&str,DBUS_TYPE_UINT16,&major); dbus_message_iter_append_basic(&str,DBUS_TYPE_UINT16,&minor); dbus_message_iter_close_container(&iter,&str); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Quit")) { gm_dbus_reply_if_needed(connection,msg); if (p->getMainWindow()) p->getMainWindow()->handle(p,FXSEL(SEL_COMMAND,GMWindow::ID_QUIT),NULL); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } DBusHandlerResult GMMediaPlayerService::player_filter(DBusConnection *connection,DBusMessage * msg,void * /*ptr*/){ DEBUG_DBUS_MESSAGE(msg); DBusMessage * reply=NULL; FXuint serial; GMPlayerManager * p = GMPlayerManager::instance(); if (dbus_message_is_method_call(msg,"org.freedesktop.DBus.Introspectable","Introspect")){ return gm_dbus_reply_string(connection,msg,mpris_player_xml); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetCaps")) { FXint caps = mpris_get_caps(p); return gm_dbus_reply_int(connection,msg,caps); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"PositionGet")) { return gm_dbus_reply_int(connection,msg,p->getPlayer()->getPositionMS()); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"VolumeSet")) { return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"VolumeGet")) { return gm_dbus_reply_int(connection,msg,p->volume()); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetStatus")) { reply = dbus_message_new_method_return(msg); if (reply) { DBusMessageIter iter; dbus_message_iter_init_append(reply,&iter); gm_mpris_get_status(&iter,p); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetMetadata")) { reply = dbus_message_new_method_return(msg); if (reply) { DBusMessageIter iter; GMTrack track; p->getTrackInformation(track); dbus_message_iter_init_append(reply,&iter); gm_mpris_track_to_dict(&iter,track); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Play")){ p->cmd_play(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Stop")){ p->cmd_stop(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Pause")){ p->cmd_pause(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Next")){ p->cmd_next(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Prev")){ p->cmd_prev(); return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"Repeat")){ return gm_dbus_reply_if_needed(connection,msg); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } DBusHandlerResult GMMediaPlayerService::tracklist_filter(DBusConnection *connection,DBusMessage * msg,void * /*ptr*/){ DEBUG_DBUS_MESSAGE(msg); DBusMessage * reply=NULL; FXuint serial; GMPlayerManager * p = GMPlayerManager::instance(); if (dbus_message_is_method_call(msg,"org.freedesktop.DBus.Introspectable","Introspect")){ return gm_dbus_reply_string(connection,msg,mpris_tracklist_xml); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetMetadata")) { reply = dbus_message_new_method_return(msg); if (reply) { DBusMessageIter iter; GMTrack track; p->getTrackInformation(track); dbus_message_iter_init_append(reply,&iter); gm_mpris_track_to_dict(&iter,track); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetLength")) { return gm_dbus_reply_int(connection,msg,0); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"GetCurrentTrack")) { return gm_dbus_reply_int(connection,msg,0); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"AddTrack")) { return gm_dbus_reply_int(connection,msg,1); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"DelTrack")) { return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"SetLoop")) { return gm_dbus_reply_if_needed(connection,msg); } else if (dbus_message_is_method_call(msg,MPRIS_DBUS_INTERFACE,"SetRandom")) { return gm_dbus_reply_if_needed(connection,msg); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } gogglesmm-0.12.7/src/GMRemote.cpp0000644000175000001440000002741511555305512015272 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "icons.h" #include "gmdefs.h" #include #include #include "GMRemote.h" #include "GMWindow.h" #include "GMList.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMIconTheme.h" // Map FXDEFMAP(GMRemote) GMRemoteMap[]={ FXMAPFUNC(SEL_UPDATE, GMRemote::ID_VOLUME_BUTTON, GMRemote::onUpdVolumeButton), FXMAPFUNC(SEL_COMMAND, GMRemote::ID_VOLUME_SLIDER, GMRemote::onCmdVolume), FXMAPFUNC(SEL_CHANGED, GMRemote::ID_VOLUME_SLIDER, GMRemote::onCmdVolume), FXMAPFUNC(SEL_MOUSEWHEEL, GMRemote::ID_VOLUME_BUTTON, GMRemote::onCmdVolumeButton), FXMAPFUNC(SEL_MOUSEWHEEL, 0, GMRemote::onCmdVolumeButton), }; // Implementation FXIMPLEMENT(GMRemote,FXMainWindow,GMRemoteMap,ARRAYNUMBER(GMRemoteMap)) GMRemote::GMRemote(FXApp* a,FXObject * tgt,FXSelector msg):FXMainWindow(a,"Goggles Music Manager",NULL,NULL,DECOR_BORDER|DECOR_TITLE|DECOR_CLOSE|DECOR_STRETCHABLE,0,0,0,0,3,3,3,3,3,3){ flags|=FLAG_ENABLED; setTarget(tgt); setSelector(msg); setIcon(GMIconTheme::instance()->icon_applogo); setMiniIcon(GMIconTheme::instance()->icon_applogo_small); GMIconTheme::instance()->loadSmall(icon_home,"go-home",FXApp::instance()->getBaseColor()); #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getApp()->getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getApp()->getNormalFont()->getFontDesc(); #endif fontdescription.weight = FXFont::Bold; fontdescription.size += 10; font_title = new FXFont(getApp(),fontdescription); font_title->create(); img_default = new FXPNGImage(getApp(),about_png); img_default->scale(64,64,1); img_default->blend(getApp()->getBackColor()); img_default->create(); cover_label = new FXImageFrame(this,img_default,LAYOUT_SIDE_LEFT|FRAME_SUNKEN|LAYOUT_FIX_WIDTH|JUSTIFY_CENTER_X|JUSTIFY_CENTER_Y|LAYOUT_FILL_Y,0,0,64,64); cover_label->setBackColor(getApp()->getBackColor()); /// Popup Volume Menu volumecontrol = new FXPopup(this,POPUP_VERTICAL|FRAME_RAISED|FRAME_THICK|POPUP_SHRINKWRAP); volumeslider = new FXSlider(volumecontrol,this,GMRemote::ID_VOLUME_SLIDER,LAYOUT_FIX_HEIGHT|LAYOUT_FIX_WIDTH|SLIDER_VERTICAL|SLIDER_TICKS_RIGHT|SLIDER_TICKS_LEFT|SLIDER_INSIDE_BAR,0,0,20,100); volumeslider->setTickDelta(10); volumeslider->setRange(0,100); volumeslider->setIncrement(10); FXHorizontalFrame * buttons = new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0,3,3,0,0); new FXButton(buttons,tr("\tShow Browser\tShow Browser"),icon_home,GMPlayerManager::instance(),GMPlayerManager::ID_SHOW_MANAGER,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXVerticalSeparator(buttons,LAYOUT_FILL_Y|SEPARATOR_GROOVE); new FXButton(buttons,tr("\tStart Playback\tStart Playback"),GMIconTheme::instance()->icon_play,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_PLAYPAUSEMENU,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXButton(buttons,tr("\tStop Playback\tStop Playback"),GMIconTheme::instance()->icon_stop,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_STOP,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXVerticalSeparator(buttons,LAYOUT_FILL_Y|SEPARATOR_GROOVE); new FXButton(buttons,tr("\tPlay Previous Track\tPlay previous track."),GMIconTheme::instance()->icon_prev,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_PREV,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXButton(buttons,tr("\tPlay Next Track\tPlay next track."),GMIconTheme::instance()->icon_next,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_NEXT,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXVerticalSeparator(buttons,LAYOUT_FILL_Y|SEPARATOR_GROOVE); time_label =new FX7Segment(buttons,"--:--",SEVENSEGMENT_SHADOW|LAYOUT_CENTER_Y); time_label->setCellWidth(10); time_label->setCellHeight(15); new FXVerticalSeparator(buttons,LAYOUT_FILL_Y|SEPARATOR_GROOVE); volumebutton = new FXMenuButton(buttons,tr("\tAdjust Volume\tAdjust Volume"),NULL,volumecontrol,MENUBUTTON_NOARROWS|MENUBUTTON_ATTACH_LEFT|MENUBUTTON_UP|MENUBUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y); volumebutton->setTarget(this); volumebutton->setSelector(ID_VOLUME_BUTTON); new FXSeparator(this,LAYOUT_SIDE_BOTTOM|SEPARATOR_GROOVE|LAYOUT_FILL_X); FXVerticalFrame * info = new FXVerticalFrame(this,LAYOUT_CENTER_Y|FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,2,2,2,2,0,0); title_label = new FXTextField(info,20,NULL,0,FRAME_NONE|TEXTFIELD_READONLY,0,0,0,0,0,0,0,0); title_label->setBackColor(getApp()->getBaseColor()); title_label->setFont(font_title); title_label->setDefaultCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); title_label->setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); title_label->disable(); artistalbum_label = new FXTextField(info,30,NULL,0,FRAME_NONE|TEXTFIELD_READONLY,0,0,0,0,0,0,0,0); artistalbum_label->setBackColor(getApp()->getBaseColor()); artistalbum_label->setDefaultCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); getAccelTable()->addAccel(parseAccel("F11"),GMPlayerManager::instance(),FXSEL(SEL_COMMAND,GMPlayerManager::ID_SHOW_MANAGER)); getAccelTable()->addAccel(parseAccel("Ctrl-M"),GMPlayerManager::instance(),FXSEL(SEL_COMMAND,GMPlayerManager::ID_SHOW_MANAGER)); getAccelTable()->addAccel(parseAccel("Ctrl-W"),this,FXSEL(SEL_CLOSE,0)); getAccelTable()->addAccel(parseAccel("Ctrl-Q"),GMPlayerManager::instance()->getMainWindow(),FXSEL(SEL_COMMAND,GMWindow::ID_QUIT)); getAccelTable()->addAccel(parseAccel("Ctrl-P"),GMPlayerManager::instance()->getMainWindow(),FXSEL(SEL_COMMAND,GMWindow::ID_PLAYPAUSEMENU)); getAccelTable()->addAccel(parseAccel("Ctrl-\\"),GMPlayerManager::instance()->getMainWindow(),FXSEL(SEL_COMMAND,GMWindow::ID_STOP)); getAccelTable()->addAccel(parseAccel("Ctrl-["),GMPlayerManager::instance()->getMainWindow(),FXSEL(SEL_COMMAND,GMWindow::ID_PREV)); getAccelTable()->addAccel(parseAccel("Ctrl-]"),GMPlayerManager::instance()->getMainWindow(),FXSEL(SEL_COMMAND,GMWindow::ID_NEXT)); GMIconTheme::instance()->loadSmall(icon_volume_high,"audio-volume-high",FXApp::instance()->getBaseColor()); GMIconTheme::instance()->loadSmall(icon_volume_medium,"audio-volume-medium",FXApp::instance()->getBaseColor()); GMIconTheme::instance()->loadSmall(icon_volume_low,"audio-volume-low",FXApp::instance()->getBaseColor()); GMIconTheme::instance()->loadSmall(icon_volume_muted,"audio-volume-muted",FXApp::instance()->getBaseColor()); reset(); if (GMPlayerManager::instance()->getMainWindow()->getSmallCover()) cover_label->setImage(GMPlayerManager::instance()->getMainWindow()->getSmallCover()); update_volume_display(GMPlayerManager::instance()->volume()); } // Destroy main window GMRemote::~GMRemote(){ volumeslider->setTarget(NULL); volumeslider->setSelector(0); volumebutton->setMenu(NULL); } void GMRemote::writeRegistry(){ if (shown()) { getApp()->reg().writeIntEntry("window","remote-x",getX()); getApp()->reg().writeIntEntry("window","remote-y",getY()); getApp()->reg().writeIntEntry("window","remote-width",getWidth()); getApp()->reg().writeIntEntry("window","remote-height",getHeight()); } } void GMRemote::updateCover(FXImage * cover) { if (cover==NULL) { cover_label->setImage(img_default); } else { cover_label->setImage(cover); } } void GMRemote::display(const GMTrack & track){ FXString tip = GMStringFormat("%s\n%s\n%s (%d)",track.title.text(),track.artist.text(),track.album.text(),track.year); title_label->setText(track.title); title_label->setJustify(JUSTIFY_LEFT); title_label->setCursorPos(0); title_label->setAnchorPos(0); title_label->makePositionVisible(0); title_label->setTipText(tip); artistalbum_label->setText("by " + track.artist + " from " + track.album); artistalbum_label->show(); artistalbum_label->setCursorPos(0); artistalbum_label->setAnchorPos(0); artistalbum_label->makePositionVisible(0); artistalbum_label->setTipText(tip); recalc(); } void GMRemote::reset(){ title_label->setText("Goggles Music Manager"); title_label->setJustify(JUSTIFY_CENTER_X); title_label->setLayoutHints(LAYOUT_CENTER_Y|LAYOUT_FILL_X); title_label->setTipText(FXString::null); artistalbum_label->setText(FXString::null); artistalbum_label->setTipText(FXString::null); artistalbum_label->hide(); time_label->setText("--:--"); recalc(); layout(); } void GMRemote::elapsed_time(FXint hours,FXint minutes,FXint seconds,FXint,FXbool playing){ if (playing) { if (hours>0) time_label->setText(GMStringFormat("%d:%.2d:%.2d",hours,minutes,seconds)); else time_label->setText(GMStringFormat("%.2d:%.2d",minutes,seconds)); } else { time_label->setText("--:--"); } } void GMRemote::update_volume_display(FXint level) { if (level<=0) volumebutton->setIcon(icon_volume_muted); else if (level<=33) volumebutton->setIcon(icon_volume_low); else if (level<=66) volumebutton->setIcon(icon_volume_medium); else volumebutton->setIcon(icon_volume_high); volumeslider->setValue(level); } // Create and show window void GMRemote::create(){ FXMainWindow::create(); if (getApp()->reg().readIntEntry("window","remote-x",-1)!=-1) { FXint xx=getApp()->reg().readIntEntry("window","remote-x",getX()); FXint yy=getApp()->reg().readIntEntry("window","remote-y",getY()); if (getApp()->reg().readIntEntry("window","remote-width",-1)!=-1) { FXint ww=getApp()->reg().readIntEntry("window","remote-width",getDefaultWidth()); FXint hh=getApp()->reg().readIntEntry("window","remote-height",getDefaultHeight()); position(xx,yy,ww,hh); } else { move(xx,yy); } } else { place(PLACEMENT_SCREEN); } gm_set_application_icon(this); } bool GMRemote::doesOverrideRedirect() const { return FALSE; } long GMRemote::onCmdVolume(FXObject*,FXSelector,void*ptr){ FXint level = (FXint)(FXival)ptr; GMPlayerManager::instance()->volume(level); GMPlayerManager::instance()->getMainWindow()->update_volume_display(level); update_volume_display(level); return 1; } long GMRemote::onCmdVolumeButton(FXObject*,FXSelector sel,void*ptr){ volumeslider->handle(this,FXSEL(FXSELTYPE(sel),0),ptr); return 1; } long GMRemote::onUpdVolumeButton(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->audio_device_opened()) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } gogglesmm-0.12.7/src/GMFilename.cpp0000644000175000001440000004236612052065134015555 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "FXTextCodec.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "GMFilename.h" /* Conditionals ------------ ?c => display a if c is not empty, display b if c is empty) ?c => display c if not empty T => track title A => album title P => album artist name p => track artist name G => genre N => 2 digit track number n => track number d => disc number y => track year */ const char * gmcodecnames[]={ "7-bit Ascii", "UTF-8 Unicode", "ISO 8859-1", "ISO 8859-2", "ISO 8859-3", "ISO 8859-4", "ISO 8859-5", "ISO 8859-6", "ISO 8859-7", "ISO 8859-8", "ISO 8859-9", "ISO 8859-10", "ISO 8859-11", "ISO 8859-13", "ISO 8859-14", "ISO 8859-15", "ISO 8859-16", "CP-437", "CP-850", "CP-852", "CP-855", "CP-856", "CP-857", "CP-860", "CP-861", "CP-862", "CP-863", "CP-864", "CP-865", "CP-866", "CP-869", "CP-874", "CP-1250", "CP-1251", "CP-1252", "CP-1253", "CP-1254", "CP-1255", "CP-1256", "CP-1257", "CP-1258", "KOI8-R", NULL, }; using namespace GMFilename; namespace GMFilename { FXTextCodec * findcodec(const FXuint & codec) { switch(codec) { case ENCODING_ASCII : return NULL; break; case ENCODING_UTF8 : return new FXUTF8Codec; break; case ENCODING_8859_1 : return new FX88591Codec; break; case ENCODING_8859_2 : return new FX88592Codec; break; case ENCODING_8859_3 : return new FX88593Codec; break; case ENCODING_8859_4 : return new FX88594Codec; break; case ENCODING_8859_5 : return new FX88595Codec; break; case ENCODING_8859_6 : return new FX88596Codec; break; case ENCODING_8859_7 : return new FX88597Codec; break; case ENCODING_8859_8 : return new FX88598Codec; break; case ENCODING_8859_9 : return new FX88599Codec; break; case ENCODING_8859_10 : return new FX885910Codec; break; case ENCODING_8859_11 : return new FX885911Codec; break; case ENCODING_8859_13 : return new FX885913Codec; break; case ENCODING_8859_14 : return new FX885914Codec; break; case ENCODING_8859_15 : return new FX885915Codec; break; case ENCODING_8859_16 : return new FX885916Codec; break; case ENCODING_CP437 : return new FXCP437Codec; break; case ENCODING_CP850 : return new FXCP850Codec; break; case ENCODING_CP852 : return new FXCP852Codec; break; case ENCODING_CP855 : return new FXCP855Codec; break; case ENCODING_CP856 : return new FXCP856Codec; break; case ENCODING_CP857 : return new FXCP857Codec; break; case ENCODING_CP860 : return new FXCP860Codec; break; case ENCODING_CP861 : return new FXCP861Codec; break; case ENCODING_CP862 : return new FXCP862Codec; break; case ENCODING_CP863 : return new FXCP863Codec; break; case ENCODING_CP864 : return new FXCP864Codec; break; case ENCODING_CP865 : return new FXCP865Codec; break; case ENCODING_CP866 : return new FXCP866Codec; break; case ENCODING_CP869 : return new FXCP869Codec; break; case ENCODING_CP874 : return new FXCP874Codec; break; case ENCODING_CP1250 : return new FXCP1250Codec; break; case ENCODING_CP1251 : return new FXCP1251Codec; break; case ENCODING_CP1252 : return new FXCP1252Codec; break; case ENCODING_CP1253 : return new FXCP1253Codec; break; case ENCODING_CP1254 : return new FXCP1254Codec; break; case ENCODING_CP1255 : return new FXCP1255Codec; break; case ENCODING_CP1256 : return new FXCP1256Codec; break; case ENCODING_CP1257 : return new FXCP1257Codec; break; case ENCODING_CP1258 : return new FXCP1258Codec; break; case ENCODING_KOIR8 : return new FXKOI8RCodec; break; default : return NULL; } return NULL; } /* 0) trim white spaces 1) only want printable characters 2) substitute spaces for underscores [optional] 3) make everything lowercase [optional] 4) do not use any of the shell dangerous character set \'\\#~!\"$&();<>|`^*?[]/ */ static FXString filter(const FXString & input,const FXString & forbidden,FXuint options){ // const FXString forbidden = "\'\\#~!\"$&();<>|`^*?[]/.:"; // Allowed %+,-=@_{} FXString result; FXwchar w; FXint i; FXbool lastspace=false; for (i=0;iutf2mb(&c,1,&input[i],input.extent(i)); if (len>0 && c!=0x1A) { result+=c; } else { input_decompose.assign(&input[i],input.extent(i)); #if FOXVERSION < FXVERSION(1,7,29) input_decompose = decompose(input_decompose,DecCompat); #else input_decompose = decompose(input_decompose,DecomposeCompat); #endif for (j=0;jutf2mb(&c,1,&input_decompose[j],input_decompose.extent(j)); if (len>0 && c!=0x1A) { result+=c; } } } } return result; } /* convert UTF8 to given 7 bit assci */ static FXString convert_and_decompose(const FXString & input) { register FXint i=0; FXString result; #if FOXVERSION < FXVERSION(1,7,29) FXString in = decompose(input,DecCanonical); #else FXString in = decompose(input,DecomposeCanonical); #endif for (i=0;i(codec)==NULL) result = convert_and_decompose(result,codec); return result; } static FXString to_8bit_ascii(const FXString & input,const FXString & forbidden,FXuint opts) { FXString result; /// Filter the input result = filter(input,forbidden,opts); /// Make sure it is properly composed. Should we do this? #if FOXVERSION < FXVERSION(1,7,29) result = compose(result,DecCompat); #else result = compose(result,DecomposeCompat); #endif /// convert to given codec. result = convert_and_decompose(result); /// Return result return result; } static FXString convert(const FXString & input,FXTextCodec * codec,const FXString & forbidden,FXuint opts) { if (codec) return to_8bit_codec(input,codec,forbidden,opts); else return to_8bit_ascii(input,forbidden,opts); } static FXString get_field(FXchar field,const GMTrack & track,FXTextCodec * codec,const FXString & forbidden,FXuint opts){ switch(field) { case 'T': return convert(track.title,codec,forbidden,opts); break; case 'A': return convert(track.album,codec,forbidden,opts); break; case 'P': return convert(track.album_artist,codec,forbidden,opts); break; case 'p': return convert(track.artist,codec,forbidden,opts); break; case 'G': return convert(track.genre,codec,forbidden,opts); break; case 'N': return GMStringFormat("%.2d",GMTRACKNO(track.no)); break; case 'n': return GMStringVal(GMTRACKNO(track.no)); break; case 'd': return GMStringVal(GMDISCNO(track.no)); break; case 'y': return GMStringVal(track.year); break; } return FXString::null; } static FXbool eval_field(FXchar field,const GMTrack & track,FXTextCodec * codec,const FXString & forbidden,FXuint opts){ switch(field) { case 'T': return !convert(track.title,codec,forbidden,opts).empty(); break; case 'A': return !convert(track.album,codec,forbidden,opts).empty(); break; case 'P': return !convert(track.album_artist,codec,forbidden,opts).empty(); break; case 'p': return !convert(track.artist,codec,forbidden,opts).empty(); break; case 'G': return !convert(track.genre,codec,forbidden,opts).empty(); break; case 'N': return GMTRACKNO(track.no)!=0; break; case 'n': return GMTRACKNO(track.no)!=0; break; case 'd': return GMDISCNO(track.no)!=0; break; case 'y': return track.year!=0; break; } return false; } FXString format_track(const GMTrack & track,const FXString & path,const FXString & forbidden,const FXuint & options,FXTextCodec * textcodec){ FXString field; FXwchar w; /// Valid field identifiers const FXchar valid[]="TAPpGNndy"; /// Condition Stack FXint depth=0; FXArray cs(1); cs[0]=true; FXString result; /// Parse the field entries for (FXint i=0;i') { depth--; cs.erase(cs.no()-1); continue; } } /// Check beginning of conditional if (path[i]=='?' && strchr(valid,path[i+1]) ) { /// Condition with if else clause if (path[i+2]=='<') { /// condition is true if eval_fied returns true and the parent condition is also true. cs.append(cs[depth] && eval_field(path[i+1],track,textcodec,forbidden,options)); i+=2; depth++; continue; } /// Simplified condition just display if not empty else if (cs[depth]) { if (eval_field(path[i+1],track,textcodec,forbidden,options)) { field = get_field(path[i+1],track,textcodec,forbidden,options); if (field.empty()) result.trim(); else result+=field; } i+=1; continue; } } /// only add stuff if our current condition allows it if (cs[depth]) { /// get field if (path[i]=='%' && strchr(valid,path[i+1]) ) { field = get_field(path[i+1],track,textcodec,forbidden,options); if (field.empty()) result.trim(); else result+=field; i+=1; continue; } /// Add anything else w = path.wc(i); result.append(&w,1); } } result.trim(); return result; } FXbool create(FXString & result,const GMTrack & track, const FXString & format,const FXString & forbidden,const FXuint & options,FXTextCodec * textcodec) { FXString path; /// Expand Environment Variables and such... path = FXPath::expand(format); /// Make absolute if (!FXPath::isAbsolute(path)) { path = FXPath::absolute(FXPath::directory(track.mrl),path); } /// Simplify things path = FXPath::simplify(path); /// Parse field entries result = format_track(track,path,forbidden,options,textcodec); /// Add extension result+="."; if (options&LOWERCASE_EXTENSION || options&LOWERCASE) result.append(FXPath::extension(track.mrl).lower()); else result.append(FXPath::extension(track.mrl)); return true; } void parse(GMTrack & track,const FXString & mask,FXuint options) { FXint nsep=0,i,j; FXString input,field; FXString dir; FXchar sep,item; FXint beg=0,end=0; // Determine number of path separators for (i=0;i=mask.length()) { sep='\0'; } else if (mask[j]!='%') { i++; if (mask[j]=='\\') { j++;i++; if (j0) { field=input.mid(beg,end-beg).simplify(); if (options&REPLACE_UNDERSCORE) field.substitute('_',' '); switch(item) { case 'T' : if (options&OVERWRITE || track.title.empty()) track.title.adopt(field); break; case 'P' : if (options&OVERWRITE || track.album_artist.empty()) track.album_artist.adopt(field); break; case 'A' : if (options&OVERWRITE || track.album.empty()) track.album.adopt(field); break; case 'p' : if (options&OVERWRITE || track.artist.empty()) track.artist.adopt(field); break; case 'n' : #if FOXVERSION >= FXVERSION(1,7,12) case 'N' : if (options&OVERWRITE) track.setTrackNumber(field.toInt()); break; case 'd' : if (options&OVERWRITE) track.setDiscNumber(field.toInt()); break; #else case 'N' : if (options&OVERWRITE) track.setTrackNumber(FXIntVal(field)); break; case 'd' : if (options&OVERWRITE) track.setDiscNumber(FXIntVal(field)); break; #endif } //fxmessage("%%%c=\"%s\"\n",item,field.text()); beg=end+1; } } else { //fxmessage("eat %c: %s\n",mask[i],&input[beg]); while(input[beg]!=mask[i] && beg * ********************************************************************************* * $Id: FXAutoPtr.h,v 1.11 2007/07/09 16:02:41 fox Exp $ * ********************************************************************************/ #ifndef GMAUTOPTR_H #define GMAUTOPTR_H #if FOXVERSION < FXVERSION(1,7,0) namespace FX { /// Automatic pointer template class FXAutoPtr { private: TYPE* ptr; public: /// Construct with optional pointer FXAutoPtr(TYPE* p=NULL):ptr(p){ } /// Copy constructor from an automatic pointer with compatible type template FXAutoPtr(FXAutoPtr& orig):ptr(orig.release()){ } /// Assign from pointer FXAutoPtr& operator=(TYPE *p){ ptr=p; return *this; } /// Assign from an automatic pointer with compatible type template FXAutoPtr& operator=(FXAutoPtr& orig){ reset(orig.release()); return *this; } /// Conversion operators operator TYPE*() const { return ptr; } /// Dereference operator TYPE& operator*() const { return *ptr; } /// Follow pointer operator TYPE* operator->() const { return ptr; } /// Release hold on the pointer TYPE* release(){ TYPE* tmp=ptr; ptr=NULL; return tmp; } /// Delete old object, replace by new, if any void reset(TYPE* p=NULL){ if(p!=ptr){ delete ptr; ptr=p; } } /// Destruction deletes pointer ~FXAutoPtr(){ delete ptr; } }; } #endif #endif gogglesmm-0.12.7/src/GMApp.h0000644000175000001440000000572111524662371014225 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMAPP_H #define GMAPP_H class GMClipboard; enum { SEL_EMBED_NOTIFY = SEL_LAST, SEL_EMBED_MODAL_ON, SEL_EMBED_MODAL_OFF }; class GMApp : public FXApp { FXDECLARE(GMApp) friend class GMPlug; protected: FXID xembed; FXID xsystemtray; FXID xmanager; GMClipboard * clipboard; FXFontPtr thickfont; protected: #if FOXVERSION < FXVERSION(1,7,0) virtual bool dispatchEvent(FXRawEvent & event); #else virtual FXbool dispatchEvent(FXRawEvent & event); #endif public: static GMApp * instance(); public: GMApp(const FXString& name="Application",const FXString& vendor="FoxDefault"); static FXString getCacheDirectory(FXbool create=false); #if FOXVERSION < FXVERSION(1,7,0) virtual void init(int& argc,char** argv,bool connect=true); #else virtual void init(int& argc,char** argv,FXbool connect=true); #endif void setFont(const FXFontDesc &); void updateFont(); FXFont* getThickFont() const { return thickfont; } virtual void create(); virtual ~GMApp(); }; class GMPlug : public FXTopWindow { FXDECLARE(GMPlug) protected: FXID socket; FXuchar xembedflags; protected: #if FOXVERSION < FXVERSION(1,7,0) virtual bool doesOverrideRedirect() const; #else virtual FXbool doesOverrideRedirect() const; #endif private: GMPlug(const GMPlug*); GMPlug& operator=(const GMPlug&); protected: GMPlug(); public: long onEmbedded(FXObject*,FXSelector,void*); public: GMPlug(FXApp * app); virtual void setFocus(); virtual void create(); virtual ~GMPlug(); }; #endif gogglesmm-0.12.7/src/ap_http.cpp0000644000175000001440000005113312063215447015246 0ustar sxjusers#include "gmdefs.h" #include "ap_buffer.h" #include "ap_http.h" #ifndef WIN32 #include // for close() #include #include #include #include #include // for getaddrinfo() #endif #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif #if FOXVERSION < FXVERSION(1,7,0) #define APIntVal(x) FXIntVal((x)) #define APStringVal FXStringVal #else #define APIntVal(x) ((x).toInt()) #define APStringVal FXString::value #endif #ifndef BadHandle #ifdef WIN32 #define BadHandle INVALID_HANDLE_VALUE #else #define BadHandle -1 #endif #endif using namespace ap; namespace ap { FXint HttpStatus::type() const { if (code>=100 && code<200) return HTTP_RESPONSE_INFORMATIONAL; else if (code>=200 && code<300) return HTTP_RESPONSE_SUCCESS; else if (code>=300 && code<400) return HTTP_RESPONSE_REDIRECT; else if (code>=400 && code<500) return HTTP_RESPONSE_CLIENT_ERROR; else if (code>=500 && code<600) return HTTP_RESPONSE_SERVER_ERROR; else return HTTP_RESPONSE_FAILED; } HttpResponse::HttpResponse() : flags(0), content_length(-1), chunk_remaining(-1) { } HttpResponse::~HttpResponse() { clear(); } void HttpResponse::clear() { flags=0; content_length=-1; chunk_remaining=-1; clear_headers(); } // Read (at most) nbytes from buffer or source FXival HttpResponse::read(FXchar*ptr,FXival nbytes) { FXival nread=0; while(nbytes) { if (buffer.size()) { FXival n = buffer.read(ptr,nbytes); nread+=n; nbytes-=n; ptr+=n; } else { FXival n = readBlock(ptr,nbytes); if (n<=0) return (nread>0) ? nread : n; nread+=n; nbytes-=n; ptr+=n; } } return nread; } // Fill buffer with (at most) nbytes FXival HttpResponse::fill(FXival nbytes) { buffer.reserve(nbytes); FXival nread = readBlock((FXchar*)buffer.ptr(),nbytes); if (nread>0) { //fxmessage("buf: \"%s\"\n",buffer.data()); buffer.wroteBytes(nread); } return nread; } // Try parsing one HTTP header from buffer. If succesfull, returns // headers. Mode can either be HEADER_SINGLE_LINE or HEADER_MULTIPLE_LINES, // depending on whether headers may span multiple lines or not. FXbool HttpResponse::parse_header(FXString & line,FXuint mode) { FXint len=0,i,j,l; for (i=0;i0) line.assign((FXchar*)buffer.data(),i); buffer.readBytes(i+2); return true; } // check if header continues on the next line if (len>0) { // need more bytes if ((i+2)>=buffer.size()) return false; /// header continues on next line if (buffer[i+2]==' ' || buffer[i+2]=='\t') continue; } /// copy string line.length(len); for (j=0,l=0;ladopt(value); headers.replace(key.text(),v); } } void HttpResponse::clear_headers() { for (FXint pos=headers.first();pos<=headers.last();pos=headers.next(pos)) { FXString * field = (FXString*) headers.data(pos); delete field; } headers.clear(); } void HttpResponse::check_headers() { FXString * field = NULL; field = (FXString*) headers.find("content-length"); if (field) content_length = APIntVal(*field); field = (FXString*) headers.find("transfer-encoding"); if (field && field->contains("chunked") ) flags|=ChunkedResponse; field = (FXString*) headers.find("connection"); if (field && comparecase(*field,"close")==0) flags|=ConnectionClose; #ifdef DEBUG for (FXint pos=headers.first();pos<=headers.last();pos=headers.next(pos)) { fxmessage("%s: %s\n",headers.key(pos),((FXString*)headers.data(pos))->text()); } #endif } // Read a chunk header and set the chunksize FXbool HttpResponse::read_chunk_header(FXint & chunksize) { FXString header; FXchar clrf[2]; // We've read a previous chunk if (chunksize==0) { if (read(clrf,2)!=2 || clrf[0]!='\r' || clrf[1]!='\n') { fxwarning("http: missing line feed: %c%c\n",clrf[0],clrf[1]); return false; } } if (read_header(header,HEADER_SINGLE_LINE)) { if (header.scan("%x",&chunksize)==1) { return true; } } return false; } // Read status line and set status. FXbool HttpResponse::read_status() { FXString header; if (read_header(header,HEADER_SINGLE_LINE)) { if (header.scan("HTTP/%d.%d %d",&status.major,&status.minor,&status.code)==3 || header.scan("ICY %d",&status.code)==1){ //fxmessage("Code: %d \nVersion: %d.%d\n",status.code,status.major,status.minor); return true; } } return false; } // Read header FXbool HttpResponse::read_header(FXString & header,FXuint mode) { while(!parse_header(header,mode)) { if (fill()==-1) return false; } return true; } // Read the full message body non-chunked FXString HttpResponse::read_body() { FXString body; if (content_length==0) { return FXString::null; } else if (content_length>0) { body.length(content_length); FXival n = read(&body[0],content_length); if (n0) pos+=n; } while(n==BLOCK); if (pos>0) body.length(pos); } return body; } // Read the full message body chunked FXString HttpResponse::read_body_chunked() { FXString header; FXString body; FXint chunksize=-1; if (read_chunk_header(chunksize)) { while(chunksize) { // Resize buffer body.length(body.length()+chunksize); // Anything less than chunksize is an error if (read(&body[body.length()-chunksize],chunksize)0) { allocElms(body,content_length); FXival n = read(body,content_length); if (n!=content_length) { freeElms(body); body=NULL; return -1; } return content_length; } else if (content_length<0) { const FXint BLOCK=4096; FXint size = 0; FXival len = 0; FXival n; do { resizeElms(body,size+BLOCK); size+=BLOCK; n = read(body+len,BLOCK); if (n>0) len+=n; } while(n==BLOCK); return len; } else { return 0; } } FXival HttpResponse::read_body_chunked(FXchar *& body) { FXString header; FXint size=0; FXint chunksize=-1; body = NULL; if (read_chunk_header(chunksize)) { while(chunksize) { // Resize buffer size+=chunksize; resizeElms(body,size); // Anything less than chunksize is an error if (read(body+size-chunksize,chunksize)= 0) { FXchar * data = (FXchar*)ptr; FXival n = read(data,FXMIN(content_length,len)); if (n>0) content_length-=n; return n; } else { return read((FXchar*)ptr,len); } } FXival HttpResponse::read_body_chunked(void * ptr,FXival len) { FXchar * data = (FXchar*)ptr; FXString header; FXival nbytes=0; while(len) { if (chunk_remaining<=0) { if (!read_chunk_header(chunk_remaining)) return -1; if (chunk_remaining==0) { // Trailing Headers while(read_header(header,HEADER_MULTIPLE_LINES)) { // empty header indicates end of headers if (header.empty()) break; insert_header(header); } return nbytes; } } FXival n = read(data+nbytes,FXMIN(len,chunk_remaining)); if (n<=0) return nbytes; chunk_remaining-=n; nbytes+=n; len-=n; } return nbytes; } // Parse the response status and headers. Returns true if succesful FXint HttpResponse::parse() { FXString header; if (read_status()) { while(read_header(header,HEADER_MULTIPLE_LINES)) { // empty header indicates end of headers if (header.empty()) { check_headers(); return status.type(); } insert_header(header); } } return HTTP_RESPONSE_FAILED; } // Read the full message body into string FXString HttpResponse::body() { if (flags&HeadRequest) return FXString::null; else if (flags&ChunkedResponse) return read_body_chunked(); else return read_body(); } // Read the full message body into buffer FXival HttpResponse::body(FXchar *& out) { if (flags&HeadRequest) return 0; else if (flags&ChunkedResponse) return read_body_chunked(out); else return read_body(out); } FXival HttpResponse::readBody(void * ptr,FXival len) { if (flags&HeadRequest) return 0; else if (flags&ChunkedResponse) return read_body_chunked(ptr,len); else return read_body(ptr,len); } void HttpResponse::discard() { if (!(flags&ConnectionClose) && !(flags&HeadRequest)) { FXchar buffer[1024]; while(readBody(buffer,1024)==1024) ; } } FXString HttpResponse::getHeader(const FXString & key) const { FXString * value = (FXString*)headers.find(key.text()); if (value) return (*value); else return FXString::null; } FXint HttpResponse::getContentLength() const { return content_length; } HttpHost::HttpHost() : port(0) { } HttpHost::HttpHost(const FXString & url) { set(url); } void HttpHost::clear() { name.clear(); port=0; } FXbool HttpHost::set(const FXString & url) { FXString nn = GMURL::host(url); FXint np = GMURL::port(url); if (np==0) np=80; if (name!=nn || port!=np) { name.adopt(nn); port=np; return true; } return false; } HttpClient::HttpClient() : device(BadHandle) { } HttpClient::~HttpClient() { close(); } void HttpClient::close() { if (device!=BadHandle) { shutdown(device,SHUT_RDWR); ::close(device); device=BadHandle; } } void HttpClient::discard() { if (flags&ConnectionClose) { close(); } else { HttpResponse::discard(); } } #ifndef SOCK_NONBLOCK static FXbool ap_set_nonblocking(FXint fd) { FXint flags; flags = fcntl(fd, F_GETFL); if (flags==-1) return false; flags |= O_NONBLOCK; if (fcntl(fd,F_SETFL,flags)==-1) return false; return true; } #endif #ifndef SOCK_CLOEXEC static FXbool ap_set_closeonexec(FXint fd) { FXint flags; flags = fcntl(fd, F_GETFD); if (flags==-1) return false; flags |= FD_CLOEXEC; if (fcntl(fd,F_SETFD,flags)==-1) return false; return true; } #endif #if defined(SO_NOSIGPIPE) static FXbool ap_set_nosignal(FXint fd) { int nosignal=1; socklen_t len=sizeof(nosignal); if (setsockopt(fd,SOL_SOCKET,SO_NOSIGPIPE,&nosignal,len)==0) return true; else return false; } #else static FXbool ap_set_nosignal(FXint) { // will try to use MSG_NOSIGNAL instead... return true; } #endif static FXbool ap_set_timeout(FXInputHandle handle,FXint timeout) { struct timeval tv; memset(&tv,0,sizeof(struct timeval)); tv.tv_sec = timeout; // Receiving if (setsockopt(handle,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(struct timeval))) return false; // Sending if (setsockopt(handle,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(struct timeval))) return false; return true; } static FXInputHandle ap_create_socket(FXint domain, FXint type, FXint protocol,FXbool nonblocking,FXuint timeout=10) { FXInputHandle device = BadHandle; // On linux 2.6.27 we can pass additional socket options int opts=0; #ifdef SOCK_CLOEXEC opts|=SOCK_CLOEXEC; #endif #ifdef SOCK_NONBLOCK if (nonblocking) opts|=SOCK_NONBLOCK; #endif device = socket(domain,type|opts,protocol); if (device==BadHandle) return BadHandle; #ifndef SOCK_CLOEXEC if (!ap_set_closeonexec(device)){ ::close(device); return BadHandle; } #endif #ifndef SOCK_NONBLOCK if (nonblocking && !ap_set_nonblocking(device)){ ::close(device); return BadHandle; } #endif // Don't want signals if (!ap_set_nosignal(device)) { ::close(device); return BadHandle; } // In case of blocking sockets, set a timeout if (!nonblocking && !ap_set_timeout(device,timeout)) { ::close(device); return BadHandle; } return device; } FXbool HttpClient::open_connection() { struct addrinfo hints; struct addrinfo * list=NULL; struct addrinfo * item=NULL; FXint result; memset(&hints,0,sizeof(struct addrinfo)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_STREAM; hints.ai_flags|=(AI_NUMERICSERV|AI_ADDRCONFIG); if (flags&UseProxy) result=getaddrinfo(proxy.name.text(),APStringVal(proxy.port).text(),&hints,&list); else result=getaddrinfo(server.name.text(),APStringVal(server.port).text(),&hints,&list); if (result) return false; for (item=list;item;item=item->ai_next){ device = ap_create_socket(item->ai_family,item->ai_socktype,item->ai_protocol,(flags&UseNonBlock)); if (device == BadHandle) continue; if (connect(device,item->ai_addr,item->ai_addrlen)==0){ freeaddrinfo(list); return true; } // In case of non-blocking we need to wait for the socket to become ready to write. if (errno==EINPROGRESS || errno==EINTR || errno==EWOULDBLOCK) { if (wait_write(device)) { int socket_error=0; socklen_t socket_length=sizeof(socket_error); if (getsockopt(device,SOL_SOCKET,SO_ERROR,&socket_error,&socket_length)==0 && socket_error==0){ freeaddrinfo(list); return true; } } else { ::close(device); device=BadHandle; freeaddrinfo(list); return false; } } // Failed, try some other one. ::close(device); device=BadHandle; } if (list) freeaddrinfo(list); return false; } FXival HttpClient::writeBlock(const void * data,FXival count) { FXival nwritten=-1; do{ nwritten=::write(device,data,count); } while(nwritten<0 && errno==EINTR); return nwritten; } FXival HttpClient::readBlock(void * data,FXival count) { FXival nread=-1; do{ nread=::read(device,data,count); } while(nread<0 && errno==EINTR); return nread; } FXbool HttpClient::send(const FXchar * data,FXint len) { do { FXival n = writeBlock(data,len); if (n<=0) return false; data += n; len -= n; } while(len); return true; } void HttpClient::reset(FXbool forceclose){ if (forceclose) close(); else discard(); clear(); } FXbool HttpClient::request(const FXchar * method,const FXString & url,const FXString & headers,const FXString & body) { FXString command,path,query; // Set Server Host FXbool host_changed = server.set(url); if (flags&UseProxy) host_changed = false; // Reset Client reset(host_changed); if (compare(method,"HEAD")==0) { flags|=HeadRequest; } // Open connection if necessary if (device==BadHandle && !open_connection()){ server.clear(); return false; } // Extract path and query path = GMURL::path(url); if (path.empty()) path = "/"; query = GMURL::query(url); if (!query.empty()) path += "?" + query; // fxmessage("path: %s\n",path.text()); // Method + Path // if (flags&HttpProxy) // command = method + url + "\r\n" //else command = method; command += " " + path + " HTTP/1.1\r\n"; // Add Host command += "Host: " + server.name + "\r\n"; // Add Content Length if (body.length()) command += "Content-Length: " + APStringVal(body.length()) + "\r\n"; // Additional headers command+=headers; // End of headers command += "\r\n"; // Add body if (body.length()) command += body; // Send Command return send(command.text(),command.length()); } static FXString ap_encode_base64(const FXString & source) { const FXchar base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const FXuchar * in = (const FXuchar*)source.text(); FXint remaining = source.length() % 3; FXint length = source.length() - remaining; FXint n=0; FXString out; out.length(4*(source.length()/3)); for (int i=0;i>2)]; out[n++]=base64[((in[i]&0x3)<<4)|(in[i+1]>>4)]; out[n++]=base64[((in[i+1]&0xf)<<2)|(in[i+2]>>6)]; out[n++]=base64[(in[i+2]&0x3f)]; } if (remaining) { out[n++]=base64[(in[length]>>2)]; if (remaining>1) { out[n++]=base64[((in[length]&0x3)<<4)|(in[length+1]>>4)]; out[n++]=base64[((in[length+1]&0xf)<<2)|in[length+2]>>6]; out[n++]='='; } else { out[n++]=base64[((in[length]&0x3)<<4)]; out[n++]='='; out[n++]='='; } } return out; } FXbool HttpClient::basic(const FXchar* method, FXString url, const FXString & headers, const FXString & body) { if (request(method,url,headers,body)) { do { switch(parse()) { case HTTP_RESPONSE_INFORMATIONAL: { if (status.code==HTTP_CONTINUE) { continue; } break; } case HTTP_RESPONSE_REDIRECT : { // 304 - Document not changed. We're done // 305 - Need to use a proxy. Currently not handled // 306 - Unused if (status.code==HTTP_NOT_MODIFIED || status.code==HTTP_USE_PROXY || status.code==306) return true; url = getHeader("location"); // No url given, done here if (url.empty()) return false; // Don't do automatic redirections for non GET/HEAD requests if (comparecase(method,"GET") && comparecase(method,"HEAD")) return true; if (!request(method,url,headers,body)) { return false; } continue; break; } case HTTP_RESPONSE_CLIENT_ERROR : { if (status.code==HTTP_UNAUTHORIZED) { FXString user = GMURL::username(url); FXString password = GMURL::password(url); if (user.empty() || password.empty()) return true; FXString challenge = getHeader("www-authenticate"); if (comparecase(challenge,"basic",5)==0) { FXString auth = "Authorization: Basic " + ap_encode_base64(user+":"+password) + "\r\n"; if (!request(method,url,headers+auth,body)) { return false; } continue; } // else if (comparecase(challenge,"digest",6)==0){ // FXASSERT(0); // } } } break; case HTTP_RESPONSE_FAILED: /* something went wrong */ { #ifdef DEBUG fxmessage("HttpClient::basic() - Response Failed:\n"); FXString b((const FXchar*)buffer->data(),buffer->size()); fxmessage("%s\n",b.text()); #endif return false; break; } default: break; } return true; } while(1); } return false; } } gogglesmm-0.12.7/src/GMList.h0000644000175000001440000001171411525430601014405 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMLIST_H #define GMLIST_H extern FXint genre_list_sort(const FXListItem* pa,const FXListItem* pb); extern FXint genre_list_sort_reverse(const FXListItem* pa,const FXListItem* pb); extern FXint artist_list_sort(const FXListItem* pa,const FXListItem* pb); extern FXint artist_list_sort_reverse(const FXListItem* pa,const FXListItem* pb); extern FXint album_list_sort(const FXListItem* pa,const FXListItem* pb); extern FXint album_list_sort_reverse(const FXListItem* pa,const FXListItem* pb); extern FXint source_list_sort(const FXTreeItem* pa,const FXTreeItem* pb); extern FXint source_list_sort_reverse(const FXTreeItem* pa,const FXTreeItem* pb); class GMList; class GMListItem : public FXListItem { FXDECLARE(GMListItem) friend class GMList; private: GMListItem(const GMListItem&); GMListItem& operator=(const GMListItem&); protected: GMListItem() {} virtual void draw(const GMList* list,FXDC& dc,FXint x,FXint y,FXint w,FXint h) const; public: /// Construct new item with given text, icon, and user-data GMListItem(const FXString& text,FXIcon* ic=NULL,void* ptr=NULL): FXListItem(text,ic,ptr) { } }; class GMAlbumListItem : public GMListItem { FXDECLARE(GMAlbumListItem) friend class GMList; public: FXIntList albums; FXint year; private: GMAlbumListItem(const GMAlbumListItem&); GMAlbumListItem& operator=(const GMAlbumListItem&); protected: GMAlbumListItem() {} public: /// Construct new item with given text, icon, and user-data GMAlbumListItem(const FXString& text,FXIcon* ic=NULL,FXint id=0,FXint _year=0): GMListItem(text,ic,(void*)(FXival)(id)), year(_year) { state|=DRAGGABLE; } }; class GMList : public FXList { FXDECLARE(GMList) protected: FXFont * thickfont; FXColor rowcolor; protected: GMList(); void recompute(); virtual FXListItem *createItem(const FXString& text,FXIcon* icon,void* ptr); private: GMList(const GMList&); GMList &operator=(const GMList&); public: long onPaint(FXObject*,FXSelector,void*); public: /// Construct a list with initially no items in it GMList(FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=LIST_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0); FXColor getRowColor() const { return rowcolor; } void setRowColor(FXColor c) { rowcolor=c; update(); } void setThickFont(FXFont * f) { thickfont=f;} virtual ~GMList(); }; /// Tree list Item class GMTreeItem : public FXTreeItem { FXDECLARE(GMTreeItem) friend class GMTreeList; protected: GMTreeItem(); private: GMTreeItem(const GMTreeItem&); GMTreeItem& operator=(const GMTreeItem&); protected: virtual void draw(const FXTreeList* list,FXDC& dc,FXint x,FXint y,FXint w,FXint h) const; public: /// Constructor GMTreeItem(const FXString& text,FXIcon* oi=NULL,FXIcon* ci=NULL,void* ptr=NULL): FXTreeItem(text,oi,ci,ptr){} virtual FXuint getItemType() const { return SOURCE_UNKNOWN; } /// Return height of item as drawn in list virtual FXint getHeight(const FXTreeList* list) const; }; class GMTreeList : public FXTreeList { FXDECLARE(GMTreeList) protected: FXColor rowcolor; protected: GMTreeList(); virtual FXTreeItem* createItem(const FXString& text,FXIcon* oi,FXIcon* ci,void* ptr); private: GMTreeList(const GMTreeList&); GMTreeList& operator=(const GMTreeList&); public: long onPaint(FXObject*,FXSelector,void*); public: /// Construct a new, initially empty tree list GMTreeList(FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=TREELIST_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0); void setRowColor(FXColor c) { rowcolor=c; update(); } }; #endif gogglesmm-0.12.7/src/GMDatabase.cpp0000644000175000001440000001462311573753674015560 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" // Database GMDatabase::GMDatabase() : opened(FALSE),db(NULL){ } GMDatabase::~GMDatabase(){ close(); } FXbool GMDatabase::open(const FXString & filename){ close(); if (sqlite3_open(filename.text(),&db)!=SQLITE_OK){ return FALSE; } if (!execute("PRAGMA database_list;")) return FALSE; opened=TRUE; return TRUE; } /// Close the database void GMDatabase::close(){ if (db) { sqlite3_close(db); db=NULL; } opened=FALSE; } /// Clear the database void GMDatabase::clear(){ FXStringList tables; listTables(tables); for (FXint i=0;i=0 && track.bitrate>0) { db->setStreamBitrate(current_track,track.bitrate); if (GMPlayerManager::instance()->getTrackView()->getSource()==this) GMPlayerManager::instance()->getTrackView()->refresh(); } return true; } FXbool GMStreamSource::getTrack(GMTrack & info) const { info.clear(); info.mrl=getTrackFilename(current_track); return false; } FXString GMStreamSource::getTrackFilename(FXint id) const{ const char * url; FXString query; GMQuery q; try { query="SELECT url FROM streams WHERE id == " + GMStringVal(id) + ";"; q.compile(db->database(),query); q.execute(); url = q.getResult(0); return url; } catch(FXCompileException &){ return FXString::null; } catch(FXExecuteException &){ return FXString::null; } return url; } FXbool GMStreamSource::source_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("New Station…\t\t"),NULL,this,ID_NEW_STATION); return true; } FXbool GMStreamSource::track_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Edit…\t\t"),GMIconTheme::instance()->icon_edit,this,ID_EDIT_STATION); new GMMenuCommand(pane,fxtr("New Station…\t\t"),NULL,this,ID_NEW_STATION); new GMMenuCommand(pane,fxtr("Remove\t\tRemove."),GMIconTheme::instance()->icon_delete,this,ID_DELETE_STATION); return true; } FXbool GMStreamSource::listTracks(GMTrackList * tracklist,const FXIntList &/* albumlist*/,const FXIntList & /*genre*/){ GMQuery q; FXString query; // const FXchar * c_artist; //const FXchar * c_albumname; const FXchar * c_title; const FXchar * c_genre; // FXint time; // FXint no; FXint id; FXint bitrate; FXint queue=1; try { query = "SELECT streams.id, streams.description, streams.bitrate, genres.name " "FROM streams, genres " "WHERE genres.id == streams.genre;"; q.compile(db->database(),query); while(q.execute()){ q.getResult(0,id); c_title = q.getResult(1); q.getResult(2,bitrate); c_genre = q.getResult(3); GMStreamTrackItem * item = new GMStreamTrackItem(id,c_title,c_genre,queue++,bitrate); tracklist->appendItem((GMTrackItem*)item); } GMStreamTrackItem::max_trackno = tracklist->getFont()->getTextWidth(FXString('8',GMDBTrackItem::max_digits(queue))); } catch(FXCompileException &){ tracklist->clearItems(); return false; } catch(FXExecuteException &){ tracklist->clearItems(); return false; } return true; } long GMStreamSource::onCmdNewStation(FXObject*,FXSelector,void*){ FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("New Internet Radio Station"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("New Internet Radio Station"),fxtr("Specify url and description of new station"),NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("C&reate"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,10,5,10,10); FXMatrix * matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS); new FXLabel(matrix,fxtr("Location"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); GMTextField * location_field = new GMTextField(matrix,40,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK); new FXLabel(matrix,fxtr("Description"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); GMTextField * description_field = new GMTextField(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK); new FXLabel(matrix,fxtr("Genre"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); GMComboBox * genrebox = new GMComboBox(matrix,20,NULL,0,LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN); db->listGenres(genrebox); genrebox->setSortFunc(genre_list_sort); genrebox->setNumVisible(FXMIN(10,genrebox->getNumItems())); genrebox->sortItems(); genrebox->setCurrentItem(-1); if (dialog.execute()) { FXString url=location_field->getText().trim(); FXString name=description_field->getText().trim(); FXString genre=genrebox->getText().trim(); if (!url.empty()) { if (genre.empty()) genre=fxtr("Untitled"); db->insertStream(url,name,genre); GMPlayerManager::instance()->getTrackView()->refresh(); } } return 1; } long GMStreamSource::onCmdEditStation(FXObject*,FXSelector,void*){ GMTextField * location_field=NULL; FXIntList tracks; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Edit Internet Radio Station"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Edit Internet Radio Station"),fxtr("Update url and description of station"),NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Save"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,10,5,10,10); FXMatrix * matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS); if (tracks.no()==1) { new FXLabel(matrix,fxtr("Location"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); location_field = new GMTextField(matrix,40,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK); } new FXLabel(matrix,fxtr("Description"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); GMTextField * description_field = new GMTextField(matrix,30,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK); new FXLabel(matrix,fxtr("Genre"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); GMComboBox * genrebox = new GMComboBox(matrix,20,NULL,0,LAYOUT_FILL_X|FRAME_THICK|FRAME_SUNKEN); db->listGenres(genrebox); genrebox->setSortFunc(genre_list_sort); genrebox->setCurrentItem(-1); genrebox->setNumVisible(FXMIN(10,genrebox->getNumItems())); genrebox->sortItems(); GMStream info; if (tracks.no()==1) { db->getStream(tracks[0],info); location_field->setText(info.url); description_field->setText(info.description); genrebox->setCurrentItem(genrebox->findItem(info.genre)); } if (dialog.execute()) { FXbool changed=false; db->beginEdit(); if (tracks.no()==1 && location_field->getText()!=info.url && !location_field->getText().empty()) { db->setStreamFilename(tracks[0],location_field->getText()); changed=true; } if (description_field->getText()!=info.description && !description_field->getText().empty()){ for (FXint i=0;isetStreamDescription(tracks[i],description_field->getText()); changed=true; } if (genrebox->getText()!=info.genre && !genrebox->getText().empty()){ for (FXint i=0;isetStreamGenre(tracks[i],genrebox->getText()); changed=true; } db->endEdit(); if (changed) GMPlayerManager::instance()->getTrackView()->refresh(); } return 1; } long GMStreamSource::onCmdDeleteStation(FXObject*,FXSelector,void*){ const FXString title=fxtr("Remove Internet Radio Station(s)?"); const FXString subtitle=fxtr("Remove Internet Radio Station(s) from library?"); FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),title,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,title,subtitle,NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new FXButton(closebox,fxtr("&Remove"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); // new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); if (dialog.execute()){ FXIntList tracks; GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); db->beginDelete(); for (int i=0;iremoveStream(tracks[i])){ FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtrformat("Unable to remove station from the library.")); } } db->endDelete(); GMPlayerManager::instance()->getTrackView()->refresh(); } return 1; } long GMStreamSource::onUpdExport(FXObject*sender,FXSelector,void*){ sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } gogglesmm-0.12.7/src/GMSource.h0000644000175000001440000001240411525430601014727 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMSOURCE_H #define GMSOURCE_H #ifndef GMTRACKLIST_H #include "GMTrackList.h" #endif class GMList; /* enum { FLAG_CAN_AUTOPLAY =0x1, FLAG_CAN_FILTER =0x2, FLAG_CAN_BROWSE =0x4, FLAG_DEFAULT_BROWSE=0x8 }; */ enum { FILTER_TRACK = 0x1, FILTER_ARTIST = 0x2, FILTER_ALBUM = 0x4, FILTER_GENRE = 0x8, FILTER_ALL = (FILTER_TRACK|FILTER_ARTIST|FILTER_ALBUM|FILTER_GENRE), FILTER_DEFAULT = (FILTER_TRACK|FILTER_ARTIST|FILTER_ALBUM) }; /// Sort Function class GMTrackItem; typedef FXint (*GMTrackListSortFunc)(const GMTrackItem*,const GMTrackItem*); class GMSource : public FXObject { FXDECLARE(GMSource) protected: FXIntList genre_selection; FXIntList artist_selection; FXIntList album_selection; FXint current_track; GMTrackListSortFunc sort_browse; private: GMSource(const GMSource&); GMSource& operator=(const GMSource&); public: enum { ID_TRACK_PLAYED = 1, ID_EDIT_GENRE, ID_EDIT_ARTIST, ID_EDIT_ALBUM, ID_EDIT_TRACK, ID_COPY_ARTIST, ID_COPY_ALBUM, ID_COPY_TRACK, ID_DELETE_GENRE, ID_DELETE_ARTIST, ID_DELETE_ALBUM, ID_DELETE_TRACK, ID_PASTE, ID_DROP, ID_EXPORT, ID_LAST }; public: GMSource(); virtual void configure(GMColumnList&) const {} virtual void shuffle(GMTrackList*,FXuint) const{} virtual void orderChanged(GMTrackList*) const{} GMTrackListSortFunc getSortBrowse() const { return sort_browse; } virtual FXint getSortColumn(FXbool browse) const { if (browse) return HEADER_BROWSE; else return HEADER_ARTIST; } virtual FXIcon * getAlbumIcon(FXint,FXbool) {return NULL;} virtual FXIcon * getAlbumIcon() {return NULL;} void setCurrentTrack(FXint t) { current_track=t; } FXint getCurrentTrack() const { return current_track; } virtual FXbool hasCurrentTrack(GMSource * ) const { return false; } virtual FXbool hasTrack(const FXString &,FXint &) { return false; } virtual void resetCurrent() { current_track=-1; } virtual void markCurrent(GMTrackList * tracklist,FXint item); virtual FXbool findCurrent(GMTrackList * tracklist,GMSource * src); virtual FXbool findCurrentArtist(GMList * tracklist,GMSource * src); virtual FXbool findCurrentAlbum(GMList * tracklist,GMSource * src); virtual FXbool moveTrack(GMTrackList*,FXint,FXint) { return false;} virtual FXint getNumTracks() const; virtual FXString getTrackFilename(FXint id) const; virtual FXbool getTrack(GMTrack & info) const; virtual FXbool setTrack(GMTrack &) const { return false; } virtual FXint getType() const { return SOURCE_INVALID; } virtual FXbool getQueueColumn(FXbool) const { return false; } virtual FXbool canBrowse() const { return true; } virtual FXbool canFilter() const { return false; } virtual FXbool defaultBrowse() const { return true; } virtual FXbool autoPlay() const { return true; } virtual FXString getName() const { return FXString::null; } virtual FXString settingKey() const { return "nokey"; } virtual FXbool setFilter(const FXString&,FXuint) {return false;} virtual FXbool listGenres(GMList * genrelist,FXIcon * icon); virtual FXbool listArtists(GMList * artistlist,FXIcon * icon,const FXIntList & genrelist); virtual FXbool listAlbums(GMList * albumlist,FXIcon * icon,const FXIntList & artistlist,const FXIntList & genrelist); virtual FXbool listTracks(GMTrackList * tracklist,const FXIntList & albumlist,const FXIntList & genrelist); virtual FXbool genre_context_menu(FXMenuPane * pane); virtual FXbool artist_context_menu(FXMenuPane * pane); virtual FXbool album_context_menu(FXMenuPane * pane); virtual FXbool track_context_menu(FXMenuPane * pane); virtual FXbool source_context_menu(FXMenuPane * pane); virtual FXbool dnd_source_accepts(FXDragType*,FXuint) { return false; } virtual ~GMSource(); }; typedef FXObjectListOf GMSourceList; #endif gogglesmm-0.12.7/src/GMFontDialog.h0000644000175000001440000000601011525430601015511 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMFONTDIALOG_H #define GMFONTDIALOG_H class GMFontDialog : public FXDialogBox { FXDECLARE(GMFontDialog) protected: FXFontDesc selected; GMList * familylist; GMList * stylelist; GMList * sizelist; GMListBox * pitchlist; GMListBox * scalelist; GMTextField * sizefield; FXLabel * preview; FXFont * previewfont; protected: GMFontDialog(); private: GMFontDialog(const GMFontDialog&); GMFontDialog &operator=(const GMFontDialog&); protected: void listFontFamily(); void listFontStyle(); void listFontSize(); void previewFont(); public: enum { ID_FAMILY = FXDialogBox::ID_LAST, ID_STYLE, ID_SIZE, ID_PITCH, ID_SCALABLE, ID_SIZE_TEXT }; public: long onCmdFamily(FXObject*,FXSelector,void*); long onCmdStyle(FXObject*,FXSelector,void*); long onCmdSize(FXObject*,FXSelector,void*); long onCmdSizeText(FXObject*,FXSelector,void*); long onCmdPitch(FXObject*,FXSelector,void*); long onUpdPitch(FXObject*,FXSelector,void*); long onCmdScalable(FXObject*,FXSelector,void*); long onUpdScalable(FXObject*,FXSelector,void*); public: GMFontDialog(FXApp * app,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=400,FXint h=400); GMFontDialog(FXWindow* owner,const FXString& name,FXuint opts=DECOR_BORDER|DECOR_TITLE|DECOR_RESIZE,FXint x=0,FXint y=0,FXint w=400,FXint h=400); virtual void create(); /// Set the current font selection void setFontDesc(const FXFontDesc& fontdesc); /// Get the current font selection const FXFontDesc& getFontDesc() const; virtual ~GMFontDialog(); }; #endif gogglesmm-0.12.7/src/GMSourceView.h0000644000175000001440000000610111525430601015557 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMSOURCEVIEW_H #define GMSOURCEVIEW_H class GMTreeList; class GMSource; class GMScrollFrame; class GMSourceView : public GMScrollFrame { FXDECLARE(GMSourceView) protected: GMTreeList * sourcelist; GMHeaderButton * sourcelistheader; protected: GMSource * source; GMSource * sourcedrop; protected: GMSourceView(); FXbool listsources(); private: GMSourceView(const GMSourceView&); GMSourceView& operator=(const GMSourceView&); public: enum { ID_SOURCE_LIST_HEADER = FXVerticalFrame::ID_LAST, ID_SOURCE_LIST, ID_NEW_PLAYLIST, ID_NEW_STATION, ID_EXPORT, ID_LAST, }; public: long onCmdSourceSelected(FXObject*,FXSelector,void*); long onCmdSortSourceList(FXObject*,FXSelector,void*); long onSourceContextMenu(FXObject*,FXSelector,void*); long onDndSourceMotion(FXObject*,FXSelector,void*); long onDndSourceDrop(FXObject*,FXSelector,void*); long onCmdNewPlayList(FXObject*,FXSelector,void*); long onUpdNewPlayList(FXObject*,FXSelector,void*); long onCmdNewStation(FXObject*,FXSelector,void*); long onCmdExport(FXObject*,FXSelector,void*); long onUpdExport(FXObject*,FXSelector,void*); public: GMSourceView(FXComposite* p); void updateColors(); void updateSource(GMSource * src); void setSource(GMSource * src,FXbool makecurrent=true); GMSource * getSource() const { return source; } FXbool listSources(); void sortSources() const; void resort(); void init(); void refresh(); void clear(); void loadSettings(const FXString & key); void saveSettings(const FXString & key) const; void saveView() const; virtual ~GMSourceView(); }; #endif gogglesmm-0.12.7/src/GMQuery.cpp0000644000175000001440000002322611525430601015133 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" // Index out of range const FXchar FXExecuteException::exceptionName[]="Query Execute Failed"; const FXchar FXCompileException::exceptionName[]="Query Compile Failed"; const FXchar FXQueryException::exceptionName[]="Query Exception"; GMQuery::GMQuery() : statement(NULL) { } GMQuery::GMQuery(GMDatabase * database,const FXString & q) : statement(NULL) { compile(database,q); } void GMQuery::compile(GMDatabase * database,const FXString & q) { if (statement) { sqlite3_finalize((sqlite3_stmt*)statement); statement=NULL; } #if SQLITE_VERSION_NUMBER > 3003011 FXint result = sqlite3_prepare_v2(database->db,q.text(),-1,&statement,NULL); #else FXint result = sqlite3_prepare(database->db,q.text(),-1,&statement,NULL); #endif if (result!=SQLITE_OK){ #ifdef DEBUG fxmessage("GMQuery::compile failed (%d): %s\n",result,q.text()); fxmessage("Reason: %s\n",sqlite3_errmsg(database->db)); #endif throw FXCompileException(); } } void GMQuery::compile(GMDatabase & database,const FXString & q) { if (statement) { sqlite3_finalize((sqlite3_stmt*)statement); statement=NULL; } #if SQLITE_VERSION_NUMBER > 3003011 FXint result = sqlite3_prepare_v2(database.db,q.text(),-1,&statement,NULL); #else FXint result = sqlite3_prepare(database.db,q.text(),-1,&statement,NULL); #endif if (result!=SQLITE_OK){ #ifdef DEBUG fxmessage("GMQuery::compile failed (%d): %s\n",result,q.text()); fxmessage("Reason: %s\n",sqlite3_errmsg(database.db)); #endif throw FXCompileException(); } } FXbool GMQuery::execute() { if (statement) { FXint result = sqlite3_step(statement); switch(result) { case SQLITE_DONE: return false; break; case SQLITE_ROW : return true; break; default : reset(); throw FXExecuteException(); break; } return false; } return false; } FXbool GMQuery::perform() { if (statement) { FXint result; while(1) { result = sqlite3_step(statement); switch(result) { case SQLITE_DONE: return true; break; case SQLITE_ROW : continue; break; default : reset(); throw FXExecuteException(); break; } } } return true; } void GMQuery::clear(){ if (statement) { sqlite3_finalize((sqlite3_stmt*)statement); statement=NULL; } } /// Return number of columns the query returns FXint GMQuery::getNumFields() const { if (statement) return sqlite3_column_count((sqlite3_stmt*)statement); else return 0; } FXint GMQuery::getNumData() const { if (statement) return sqlite3_data_count((sqlite3_stmt*)statement); else return 0; } /// Return the specified column name the query returned. FXString GMQuery::getFieldName(FXint i){ if (statement) return sqlite3_column_name((sqlite3_stmt*)statement,i); else return FXString::null; } /// Return the column type for the specified column FXFieldType GMQuery::getFieldType(FXint i){ const FXchar * type=NULL; if (statement) { type = sqlite3_column_decltype((sqlite3_stmt*)statement,i); if (type==NULL) return TYPE_NULL; else if (comparecase("INTEGER",type)==0) return TYPE_INTEGER; else if (comparecase("FLOAT",type)==0) return TYPE_FLOAT; else if (comparecase("TEXT",type)==0) return TYPE_TEXT; else if (comparecase("BLOB",type)==0) return TYPE_BLOB; else return TYPE_NULL; } else { return TYPE_NULL; } } void GMQuery::setParameter(FXint p,FXint v){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_int((sqlite3_stmt*)statement,(p+1),v); } void GMQuery::setParameter(FXint p,FXuint v){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_int((sqlite3_stmt*)statement,(p+1),(FXint)v); } void GMQuery::setParameter(FXint p,FXlong v){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_int64((sqlite3_stmt*)statement,(p+1),v); } void GMQuery::setParameter(FXint p,FXdouble v){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_double((sqlite3_stmt*)statement,(p+1),v); } void GMQuery::setParameter(FXint p,FXfloat v){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_double((sqlite3_stmt*)statement,(p+1),v); } void GMQuery::setParameter(FXint p,const FXString & text){ if (!statement) fxerror("GMQuery::setParameter called without compiled query\n"); sqlite3_bind_text((sqlite3_stmt*)statement,(p+1),text.text(),-1,SQLITE_TRANSIENT); } FXint GMQuery::getNumParameters() { if (!statement) fxerror("GMQuery::getNumParameters called without compiled query\n"); return sqlite3_bind_parameter_count((sqlite3_stmt*)statement); } FXint GMQuery::getParameterIndex(const FXString & name){ if (!statement) fxerror("GMQuery::getParameterIndex called without compiled query\n"); FXint index = sqlite3_bind_parameter_index((sqlite3_stmt*)statement,name.text()); if (index==0) return -1; return (index-1); } FXString GMQuery::getParameterName(FXint p){ if (!statement) fxerror("GMQuery::getParameterName called without compiled query\n"); const FXchar * name = sqlite3_bind_parameter_name((sqlite3_stmt*)statement,p+1); if (name==NULL) return "?"; else return name; } void GMQuery::reset() { if (statement) { sqlite3_reset(statement); } } void GMQuery::getResult(FXint column,FXString & v){ if (getNumData()) v = (const FXchar *) sqlite3_column_text((sqlite3_stmt*)statement,column); } void GMQuery::getResult(FXint column,FXint & v){ if (getNumData()) v = sqlite3_column_int((sqlite3_stmt*)statement,column); } void GMQuery::getResult(FXint column,FXuint & v){ if (getNumData()) v = (FXuint) sqlite3_column_int((sqlite3_stmt*)statement,column); } void GMQuery::getResult(FXint column,FXdouble & v){ if (getNumData() && sqlite3_column_type((sqlite3_stmt*)statement,column)==SQLITE_FLOAT){ v=sqlite3_column_double((sqlite3_stmt*)statement,column); } else { v=NAN; } } void GMQuery::getResult(FXint column,FXfloat & v){ if (getNumData() && sqlite3_column_type((sqlite3_stmt*)statement,column)==SQLITE_FLOAT){ v=sqlite3_column_double((sqlite3_stmt*)statement,column); } else { v=NAN; } } void GMQuery::getResult(FXint column,FXlong & v){ if (getNumData()) v = sqlite3_column_int64((sqlite3_stmt*)statement,column); } const FXchar * GMQuery::getResult(FXint column){ if (!getNumData()) return NULL; return (const FXchar *) sqlite3_column_text((sqlite3_stmt*)statement,column); } void GMQuery::getResult(FXint column,FXbool & v){ if (getNumData()) { FXint i; i = sqlite3_column_int((sqlite3_stmt*)statement,column); v = (i==0) ? FALSE : TRUE; } } GMQuery::~GMQuery(){ clear(); } /* void fillTable(GMQuery * query,FXTable * table){ FXint integer; FXfloat real; FXString text; FXint rows=0; FXint ncols=0; table.clearItems(); if (query.execute()) { ncols=query->getNumFields(); table->setTableSize(1,ncols); for (FXint i=0;isetColumnText(i,query->getFieldName()); switch(query->getFieldType()){ case TYPE_INTEGER : query->getResult(i,integer); table->setItemTex(rows,i,FXStringVal(integer)); break; case TYPE_FLOAT : query->getResult(i,real); table->setItemText(rows,i,FXStringVal(real)); break; case TYPE_TEXT : query->getResult(i,text); table->setItemText(rows,i,text); break; } } rows++; } while(query.execute()){ table->insertRows(rows,1); for (FXint i=0;isetColumnText(i,query->getFieldName()); switch(query->getFieldType()){ case TYPE_INTEGER : query->getResult(i,integer); table->setItemTex(rows,i,FXStringVal(integer)); break; case TYPE_FLOAT : query->getResult(i,real); table->setItemText(rows,i,FXStringVal(real)); break; case TYPE_TEXT : query->getResult(i,text); table->setItemText(rows,i,text); break; } } rows++; } } */ gogglesmm-0.12.7/src/GMURL.cpp0000644000175000001440000002226111525430601014466 0ustar sxjusers/******************************************************************************** * * * U R L M a n i p u l a t i o n * * * ********************************************************************************* * Copyright (C) 2000,2011 by Jeroen van der Zijp. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see * ********************************************************************************/ #include "gmdefs.h" #if FOXVERSION < FXVERSION(1,7,0) #define UNRESERVED "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~" // Unreserved characters #define IPV6DIGITS "abcdefABCDEF0123456789:." // Stuff in IPv6 numbers #define PCTENCODED "%0123456789abcdefABCDEF" // Percent encoded characters #define GENDELIMS ":/?#[]@" // General delimiters #define SUBDELIMS "!$&'()*+,;=" // Sub-delimiters #define RESERVED ":/?#[]@!$&'()*+,;=" // Reserved characters (GENDELIMS + SUBDELIMS) #define UNSAFE "<>#%{}|^~[]`\" " // Unsafe characters #define ENCODE_THESE "<>#%{}|^~[]`\"?$&'*,;=" // Encode these for pathnames using namespace FX; /*******************************************************************************/ // URL parts class URL { public: FXint prot[2]; FXint user[2]; FXint pass[2]; FXint host[2]; FXint port[2]; FXint path[2]; FXint quer[2]; FXint frag[2]; public: URL(const FXString& string); }; // Parse string to url parts URL::URL(const FXString& string){ register FXint s=0; prot[0]=prot[1]=0; // Parse protocol if(Ascii::isLetter(string[0])){ s++; // Scan till end of scheme name while(Ascii::isAlphaNumeric(string[s]) || string[s]=='+' || string[s]=='-' || string[s]=='.') s++; // Scheme end found if(string[s]==':' && s>1){ prot[1]=s++; } else{ s=prot[0]; // Reset:- wasn't protocol after all since no ':' found } } user[0]=user[1]=s; pass[0]=pass[1]=s; host[0]=host[1]=s; port[0]=port[1]=s; // Parse hier part if(string[s]=='/' && string[s+1]=='/'){ s+=2; // Parse username user[0]=s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%",string[s])){ s++; } // Parse password user[1]=pass[0]=s; if(string[s]==':'){ pass[0]=++s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%",string[s])){ s++; } } pass[1]=s; // Check for @ after user:pass if(string[s]=='@'){ s++; } else{ s=pass[0]=pass[1]=user[1]=user[0]; // Reset:- wasn't user:pass after all since no '@' found } // Parse hostname host[0]=s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%",string[s])){ s++; } // Parse port number host[1]=port[0]=s; if(string[s]==':'){ port[0]=++s; while(Ascii::isDigit(string[s])) s++; } port[1]=s; } #ifdef WIN32 // Parse path, allowing for \ path delimiters (legacy urls) path[0]=s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%:@/\\ ",string[s])){ s++; } #else // Parse path path[0]=s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%:@/ ",string[s])){ s++; } #endif // Parse query path[1]=quer[0]=s; if(string[s]=='?'){ quer[0]=++s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%:@/?",string[s])){ s++; } } // Parse fragment quer[1]=frag[0]=s; if(string[s]=='#'){ frag[0]=++s; while(string[s] && strchr(UNRESERVED SUBDELIMS "%:@/?",string[s])){ s++; } } frag[1]=s; } // Encode control characters and characters from set using %-encoding FXString GMURL::encode(const FXString& url,const FXchar* set){ FXString result; if(!url.empty()){ register FXint p,q,c; for(p=q=0; p>4)&15]; result[q++]=FXString::hex[c&15]; // result[q++]=FXString::value2Digit[c>>4]; // result[q++]=FXString::value2Digit[c&15]; continue; } result[q++]=c; } } return result; } // Decode string containing %-encoded characters FXString GMURL::decode(const FXString& url){ FXString result; if(!url.empty()){ register FXint p,q,c; for(p=q=0; p(ptr); FXuint id,reason; FXchar * action; if (dbus_message_is_signal(msg,GALAGO_NOTIFY_INTERFACE,"NotificationClosed")){ if ((dbus_message_has_signature(msg,"u") && dbus_message_get_args(msg,NULL,DBUS_TYPE_UINT32,&id,DBUS_TYPE_INVALID)) || (dbus_message_has_signature(msg,"uu") && dbus_message_get_args(msg,NULL,DBUS_TYPE_UINT32,&id,DBUS_TYPE_UINT32,&reason,DBUS_TYPE_INVALID))) { if (id==msgid) { msgid=0; } } return 1; } else if (dbus_message_is_signal(msg,GALAGO_NOTIFY_INTERFACE,"ActionInvoked")){ if (dbus_message_has_signature(msg,"us") && dbus_message_get_args(msg,NULL,DBUS_TYPE_UINT32,&id,DBUS_TYPE_STRING,&action,DBUS_TYPE_INVALID)) { if (compare(action,"media-skip-backward")==0) { GMPlayerManager::instance()->cmd_prev(); } else if (compare(action,"media-skip-forward")==0) { GMPlayerManager::instance()->cmd_next(); } else if (compare(action,"media-playback-pause")==0) { GMPlayerManager::instance()->cmd_pause(); } else if (compare(action,"media-playback-start")==0) { GMPlayerManager::instance()->cmd_play(); } else if (compare(action,"media-playback-stop")==0) { GMPlayerManager::instance()->cmd_stop(); } else { fxmessage("unhandled action: %s\n",action); } return 1; } } return 0; } long GMNotifyDaemon::onMethod(FXObject*,FXSelector,void*){ return 1; } long GMNotifyDaemon::onNotifyServer(FXObject*,FXSelector,void*ptr){ DBusMessage * msg = reinterpret_cast(ptr); const FXchar * name=NULL; const FXchar * vendor=NULL; const FXchar * version=NULL; const FXchar * spec=NULL; if ((dbus_message_get_type(msg)==DBUS_MESSAGE_TYPE_METHOD_RETURN) && dbus_message_get_args(msg,NULL,DBUS_TYPE_STRING,&name,DBUS_TYPE_STRING,&vendor,DBUS_TYPE_STRING,&version,DBUS_TYPE_STRING,&spec,DBUS_TYPE_INVALID)) { if (compareversion(spec,"1.1")==0) { icondata="image_data"; } else if (compareversion(spec,"1.2")>=0) { icondata="image-data"; } else { icondata="icon_data"; } if (comparecase(vendor,"xfce")==0 && comparecase(name,"xfce notify daemon")==0) { flags|=IMAGE_WITHOUT_APPICON; } if (comparecase(name,"gnome-shell")==0 && comparecase(vendor,"gnome")==0) { GMPlayerManager::instance()->getPreferences().gui_tray_icon_disabled=true; flags|=ACTION_ITEMS; if (compareversion(version,"3.2.0")<0){ flags|=IMAGE_WITHOUT_APPICON; } } #ifdef DEBUG fxmessage("name: %s\n",name); fxmessage("vendor: %s\n",vendor); fxmessage("version: %s\n",version); fxmessage("spec: %s\n",spec); fxmessage("icondata: %s\n",icondata.text()); fxmessage("flags: %x\n",flags); #endif } GMPlayerManager::instance()->update_tray_icon(); return 1; } long GMNotifyDaemon::onNotifyCapabilities(FXObject*,FXSelector,void*ptr){ DBusMessage * msg = reinterpret_cast(ptr); FXchar ** caps; int ncaps; if ((dbus_message_get_type(msg)==DBUS_MESSAGE_TYPE_METHOD_RETURN) && dbus_message_get_args(msg,NULL,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING,&caps,&ncaps,DBUS_TYPE_INVALID)) { FXbool has_action_icons=false; FXbool has_actions=false; FXbool has_persistence=false; for (FXint i=0;i(ptr); FXASSERT(msg); if (dbus_message_get_type(msg)==DBUS_MESSAGE_TYPE_METHOD_RETURN) { dbus_message_get_args(msg,NULL,DBUS_TYPE_UINT32,&msgid,DBUS_TYPE_INVALID); } return 1; } void GMNotifyDaemon::reset() { if (persistent) { notify("Goggles Music Manager","",-1,NULL); } else { close(); } } void GMNotifyDaemon::close() { #ifdef DEBUG fxmessage("GMNotifyDaemon::close()\n"); #endif if (msgid>0) { DBusMessage * msg = method("CloseNotification"); if (msg) { dbus_message_append_args(msg,DBUS_TYPE_UINT32,&msgid,DBUS_TYPE_INVALID); dbus_message_set_no_reply(msg,true); bus->send(msg); } } } void GMNotifyDaemon::init() { { DBusMessage * msg = method("GetServerInformation"); send(msg,this,ID_NOTIFY_SERVER); } { DBusMessage * msg = method("GetCapabilities"); send(msg,this,ID_NOTIFY_CAPABILITIES); } } void GMNotifyDaemon::notify_track_change(const GMTrack & track,FXImage * cover){ FXString body = GMStringFormat(fxtrformat("%s\n%s (%d)"),track.artist.text(),track.album.text(),track.year); /// Dirty Hack. According to the spec, we shouldn't have to do this, /// but try finding a notification notifydaemon that actually implements it... /// http://www.galago-project.org/specs/notification/0.9/index.html body.substitute("&","&"); notify(track.title.text(),body.text(),-1,cover); } void GMNotifyDaemon::notify(const FXchar * summary,const FXchar * body,FXint timeout,FXImage* image){ FXint iw,ih,is,ibps,ichannels,isize; dbus_bool_t ialpha; const FXchar * idata=NULL; DBusMessage * msg = method("Notify"); if (msg){ DBusMessageIter iter; DBusMessageIter array; DBusMessageIter dict; DBusMessageIter value; DBusMessageIter variant; DBusMessageIter data; dbus_message_iter_init_append(msg,&iter); gm_dbus_append_string(&iter,appname); dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msgid); if (image && (flags&IMAGE_WITHOUT_APPICON)) { FXString empty; gm_dbus_append_string(&iter,empty); } else { gm_dbus_append_string(&iter,appicon); } dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&summary); dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&body); dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array); if (persistent) { if (GMPlayerManager::instance()->can_prev()) gm_dbus_append_string_pair(&array,"media-skip-backward","Previous"); if (GMPlayerManager::instance()->can_pause()) gm_dbus_append_string_pair(&array,"media-playback-pause","Pause"); else if (GMPlayerManager::instance()->can_play()) gm_dbus_append_string_pair(&array,"media-playback-start","Play"); if (GMPlayerManager::instance()->can_stop()) gm_dbus_append_string_pair(&array,"media-playback-stop","Stop"); if (GMPlayerManager::instance()->can_next()) gm_dbus_append_string_pair(&array,"media-skip-forward","Next"); } dbus_message_iter_close_container(&iter,&array); dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array); if (image && image->getData()) { // const FXchar * icon_data="icon_data"; /// spec 0.9 says "image_data". some use "icon_data" though.. // const FXchar * icon_data="image-data"; /// spec 0.9 says "image_data". some use "icon_data" though.. ialpha = true; iw = image->getWidth(); ih = image->getHeight(); is = iw*4; ibps = 8; ichannels = 4; isize = iw*ih*4; #if FOXVERSION >= FXVERSION(1,7,26) FXColor * bgra = NULL; allocElms(bgra,(iw*ih)); gm_bgra_to_rgba(image->getData(),bgra,(iw*ih)); idata = (const FXchar*)bgra; #else idata = (const FXchar*)image->getData(); #endif dbus_message_iter_open_container(&array,DBUS_TYPE_DICT_ENTRY,0,&dict); gm_dbus_append_string(&dict,icondata); dbus_message_iter_open_container(&dict,DBUS_TYPE_VARIANT,"(iiibiiay)",&variant); dbus_message_iter_open_container(&variant,DBUS_TYPE_STRUCT,NULL,&value); dbus_message_iter_append_basic(&value,DBUS_TYPE_INT32,&iw); dbus_message_iter_append_basic(&value,DBUS_TYPE_INT32,&ih); dbus_message_iter_append_basic(&value,DBUS_TYPE_INT32,&is); dbus_message_iter_append_basic(&value,DBUS_TYPE_BOOLEAN,&ialpha); dbus_message_iter_append_basic(&value,DBUS_TYPE_INT32,&ibps); dbus_message_iter_append_basic(&value,DBUS_TYPE_INT32,&ichannels); dbus_message_iter_open_container(&value,DBUS_TYPE_ARRAY,DBUS_TYPE_BYTE_AS_STRING,&data); dbus_message_iter_append_fixed_array(&data,DBUS_TYPE_BYTE,&idata,isize); dbus_message_iter_close_container(&value,&data); dbus_message_iter_close_container(&variant,&value); dbus_message_iter_close_container(&dict,&variant); dbus_message_iter_close_container(&array,&dict); #if FOXVERSION >= FXVERSION(1,7,29) freeElms(bgra); #endif } //gm_dbus_dict_append_bool(&array,"transient",true); if (persistent) { // if (GMPlayerManager::instance()->playing()) gm_dbus_dict_append_bool(&array,"resident",true); // else // gm_dbus_dict_append_bool(&array,"transient",true); gm_dbus_dict_append_bool(&array,"action-icons",true); } dbus_message_iter_close_container(&iter,&array); dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&timeout); send(msg,this,ID_NOTIFY_REPLY); } } gogglesmm-0.12.7/src/GMTaskManager.cpp0000644000175000001440000000720511714631563016234 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "gmutils.h" #include "GMApp.h" #include "GMTaskManager.h" GMTask::GMTask(FXObject*tgt,FXSelector sel) : taskmanager(NULL),mc(NULL),processing(true),target(tgt),message(sel) { } GMTask::~GMTask() { } GMTaskManager::GMTaskManager(FXObject*tgt,FXSelector sel) : processing(false),started(false),active(NULL),target(tgt),message(sel),mc(FXApp::instance()) { } GMTaskManager::~GMTaskManager() { } void GMTaskManager::setStatus(const FXString & msg) { if (target) mc.message(target,FXSEL(SEL_TASK_STATUS,message),msg.text(),msg.length()+1); } void GMTaskManager::run(GMTask* task) { mutex.lock(); tasks.append(task); task->mc = &mc; task->taskmanager = this; processing=true; if (!started) { started=true; mutex.unlock(); start(); } else { condition_task.signal(); mutex.unlock(); } } FXbool GMTaskManager::next() { mutex.lock(); if (tasks.no()) { active = tasks[0]; tasks.erase(0); } else { active=NULL; } mutex.unlock(); return ((active!=NULL) && processing); } FXbool GMTaskManager::wait() { if (processing) { if (target) mc.message(target,FXSEL(SEL_TASK_IDLE,message),NULL,0); mutex.lock(); condition_task.wait(mutex); mutex.unlock(); } return processing; } FXint GMTaskManager::run() { ap_set_thread_name("gm_taskmanager"); do { while(next()) { if (target) mc.message(target,FXSEL(SEL_TASK_RUNNING,message),NULL,0); FXint code = active->run(); mutex.lock(); if (target) { if (code) mc.message(active->target,FXSEL(SEL_TASK_CANCELLED,active->message),&active,sizeof(GMTask*)); else mc.message(active->target,FXSEL(SEL_TASK_COMPLETED,active->message),&active,sizeof(GMTask*)); active=NULL; } else { delete active; active=NULL; } mutex.unlock(); } } while(wait()); return 0; } void GMTaskManager::cancelTask() { FXMutexLock lock(mutex); if (active) active->processing=false; } void GMTaskManager::shutdown() { mutex.lock(); if (active) active->processing=false; processing=false; condition_task.signal(); mutex.unlock(); join(); started=false; } gogglesmm-0.12.7/src/GMDBus.cpp0000644000175000001440000007466011644100246014674 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMDBus.h" #include "FXThread.h" #ifndef DBUS_MAJOR_VERSION #define DBUS_MAJOR_VERSION 1 #endif #ifndef DBUS_MINOR_VERSION #define DBUS_MINOR_VERSION 0 #endif #ifndef DBUS_MICRO_VERSION #define DBUS_MICRO_VERSION 0 #endif #define DBUSVERSION ((DBUS_MICRO_VERSION) + (DBUS_MINOR_VERSION*1000) + (DBUS_MAJOR_VERSION*100000)) #define MKDBUSVERSION(major,minor,release) ((release)+(minor*1000)+(major*100000)) /*******************************************************************************************************/ /* GLOBAL INIT */ /*******************************************************************************************************/ class GMDBusTimeout; class GMDBusGlobal { private: FXMutex mutex; FXHash tm; FXHash connections; #if FOXVERSION < FXVERSION(1,7,0) FXHash watches; #endif public: GMDBusGlobal() { dbus_threads_init_default(); } GMDBus * find(DBusConnection* dc) { FXMutexLock lock(mutex); return reinterpret_cast(connections.find(dc)); } void setuphooks() { #if FOXVERSION < FXVERSION(1,7,0) for (FXint i=0;isetup_event_loop(); } } } void insert(DBusConnection * dc,GMDBus * fxdc) { FXMutexLock lock(mutex); connections.insert(dc,fxdc); } void remove(DBusConnection * dc) { FXMutexLock lock(mutex); connections.remove(dc); } #if FOXVERSION < FXVERSION(1,7,0) DBusWatch * find(FXint fd) { FXMutexLock lock(mutex); return (DBusWatch*)watches.find((void*)(FXival)fd); } void insert(FXint fd,DBusWatch * watch){ FXMutexLock lock(mutex); watches.insert((void*)(FXival)fd,watch); } void remove(FXint fd){ FXMutexLock lock(mutex); watches.remove((void*)(FXival)fd); } #endif GMDBusTimeout * find(DBusTimeout*t) { return reinterpret_cast(tm.find(t)); } void insert(DBusTimeout*t,GMDBusTimeout*f) { tm.insert(t,f); } void remove(DBusTimeout*t) { tm.remove(t); } }; static GMDBusGlobal fxdbus; class GMDBusTimeout : public FXObject { FXDECLARE(GMDBusTimeout); protected: DBusTimeout* timeout; FXuchar flags; protected: GMDBusTimeout(); private: GMDBusTimeout(const GMDBusTimeout*); GMDBusTimeout& operator=(const GMDBusTimeout&); protected: enum { FLAG_CALLBACK = 0x1, FLAG_REMOVED = 0x2 }; public: enum { ID_TIMEOUT = 1 }; public: long onTimeout(FXObject*,FXSelector,void*); public: GMDBusTimeout(DBusTimeout *t); void add(); void remove(); ~GMDBusTimeout(); }; FXDEFMAP(GMDBusTimeout) GMDBusTimeoutMap[]={ FXMAPFUNC(SEL_TIMEOUT,GMDBusTimeout::ID_TIMEOUT,GMDBusTimeout::onTimeout), }; FXIMPLEMENT(GMDBusTimeout,FXObject,GMDBusTimeoutMap,ARRAYNUMBER(GMDBusTimeoutMap)); GMDBusTimeout::GMDBusTimeout() { } GMDBusTimeout::GMDBusTimeout(DBusTimeout *t) : timeout(t),flags(0) { fxdbus.insert(timeout,this); } GMDBusTimeout::~GMDBusTimeout() { fxdbus.remove(timeout); } void GMDBusTimeout::add() { flags&=~FLAG_REMOVED; FXApp::instance()->addTimeout(this,GMDBusTimeout::ID_TIMEOUT,TIME_MSEC(dbus_timeout_get_interval(timeout))); } void GMDBusTimeout::remove() { if (flags&FLAG_CALLBACK) { flags|=FLAG_REMOVED; return; } FXApp::instance()->removeTimeout(this,GMDBusTimeout::ID_TIMEOUT); delete this; } static dbus_bool_t fxdbus_addtimeout(DBusTimeout *timeout,void */*ptr*/) { // fxmessage("fxdbus_addtimeout %p\n",timeout); GMDBusTimeout * tm = fxdbus.find(timeout); if (tm==NULL) tm = new GMDBusTimeout(timeout); tm->add(); return true; } static void fxdbus_removetimeout(DBusTimeout *timeout,void * /*data*/) { // fxmessage("fxdbus_removetimeout %p\n",timeout); GMDBusTimeout * tm = fxdbus.find(timeout); if (tm) tm->remove(); } static void fxdbus_toggletimeout(DBusTimeout *timeout,void* data) { // fxmessage("fxdbus_toggletimeout %p\n",timeout); if (dbus_timeout_get_enabled(timeout) && dbus_timeout_get_interval(timeout)>0) fxdbus_addtimeout(timeout,data); else fxdbus_removetimeout(timeout,data); } long GMDBusTimeout::onTimeout(FXObject*,FXSelector,void*){ // fxmessage("onTimeout() %p {\n",timeout); flags|=FLAG_CALLBACK; dbus_timeout_handle(timeout); if (flags&FLAG_REMOVED) { delete this; fxmessage("}\n"); return 1; } else { if (dbus_timeout_get_enabled(timeout) && dbus_timeout_get_interval(timeout)>0 && !FXApp::instance()->hasTimeout(this,ID_TIMEOUT)){ FXApp::instance()->addTimeout(this,GMDBusTimeout::ID_TIMEOUT,TIME_MSEC(dbus_timeout_get_interval(timeout))); } } flags&=~FLAG_CALLBACK; // fxmessage("}\n"); return 1; } /*******************************************************************************************************/ /* Call Backs */ /*******************************************************************************************************/ static dbus_bool_t fxdbus_addwatch(DBusWatch *watch,void * data) { FXTRACE((35,"fxdbus_addwatch()\n")); GMDBus * dc = reinterpret_cast(data); FXuint mode = INPUT_EXCEPT; FXuint flags = dbus_watch_get_flags(watch); /// If it's not enabled, we're not going to add it if (!dbus_watch_get_enabled(watch)) return true; if (flags&DBUS_WATCH_READABLE) mode|=INPUT_READ; if (flags&DBUS_WATCH_WRITABLE) mode|=INPUT_WRITE; #if DBUSVERSION == MKDBUSVERSION(1,1,20) || DBUSVERSION >= MKDBUSVERSION(1,2,0) #if FOXVERSION < FXVERSION(1,7,0) fxdbus.insert(dbus_watch_get_unix_fd(watch),watch); return FXApp::instance()->addInput((FXInputHandle)dbus_watch_get_unix_fd(watch),mode,dc,GMDBus::ID_HANDLE); #else return FXApp::instance()->addInput(dc,GMDBus::ID_HANDLE,(FXInputHandle)dbus_watch_get_unix_fd(watch),mode,watch); #endif #else #if FOXVERSION < FXVERSION(1,7,0) fxdbus.insert(dbus_watch_get_fd(watch),watch); return FXApp::instance()->addInput((FXInputHandle)dbus_watch_get_fd(watch),mode,dc,GMDBus::ID_HANDLE); #else return FXApp::instance()->addInput(dc,GMDBus::ID_HANDLE,(FXInputHandle)dbus_watch_get_fd(watch),mode,watch); #endif #endif } static void fxdbus_removewatch(DBusWatch *watch,void *) { FXTRACE((35,"fxdbus_removewatch()\n")); /* FXuint mode=INPUT_EXCEPT; unsigned int flags = dbus_watch_get_flags(watch); if (flags&DBUS_WATCH_READABLE) mode|=INPUT_READ; if (flags&DBUS_WATCH_WRITABLE) { mode|=INPUT_WRITE; return; } */ FXuint mode=INPUT_READ|INPUT_WRITE|INPUT_EXCEPT; #if DBUSVERSION == MKDBUSVERSION(1,1,20) || DBUSVERSION >= MKDBUSVERSION(1,2,0) #if FOXVERSION < FXVERSION(1,7,0) fxdbus.remove(dbus_watch_get_unix_fd(watch)); #endif FXApp::instance()->removeInput(dbus_watch_get_unix_fd(watch),mode); #else #if FOXVERSION < FXVERSION(1,7,0) fxdbus.remove(dbus_watch_get_fd(watch)); #endif FXApp::instance()->removeInput(dbus_watch_get_fd(watch),mode); #endif } static void fxdbus_togglewatch(DBusWatch *watch,void* data) { FXTRACE((35,"fxdbus_togglewatch()\n")); if (dbus_watch_get_enabled(watch)) fxdbus_addwatch(watch,data); else fxdbus_removewatch(watch,data); } static void fxdbus_wakeup(void *){ /// To Do } /*******************************************************************************************************/ /* PUBLIC API */ /*******************************************************************************************************/ FXDEFMAP(GMDBus) GMDBusMap[]={ FXMAPFUNC(SEL_IO_READ,GMDBus::ID_HANDLE,GMDBus::onHandleRead), FXMAPFUNC(SEL_IO_WRITE,GMDBus::ID_HANDLE,GMDBus::onHandleWrite), FXMAPFUNC(SEL_IO_EXCEPT,GMDBus::ID_HANDLE,GMDBus::onHandleExcept), FXMAPFUNC(SEL_CHORE,GMDBus::ID_DISPATCH,GMDBus::onDispatch) }; FXIMPLEMENT(GMDBus,FXObject,GMDBusMap,ARRAYNUMBER(GMDBusMap)); GMDBus::GMDBus() : dc(NULL) { } GMDBus::~GMDBus(){ if (dc) { fxdbus.remove(dc); dbus_connection_unref(dc); dc=NULL; FXApp::instance()->removeChore(this,ID_DISPATCH); } } GMDBus * GMDBus::find(DBusConnection * dc) { return fxdbus.find(dc); } void GMDBus::initEventLoop() { fxdbus.setuphooks(); } FXbool GMDBus::open(DBusBusType bustype/*=DBUS_BUS_SESSION*/){ FXASSERT(dc==NULL); dc = dbus_bus_get(bustype,NULL); if (dc==NULL) return false; if (fxdbus.find(dc)) { dbus_connection_unref(dc); dc=NULL; return false; } fxdbus.insert(dc,this); dbus_connection_set_exit_on_disconnect(dc,false); return true; } FXbool GMDBus::connected() const { if (dc) return dbus_connection_get_is_connected(dc); else return false; } FXbool GMDBus::authenticated() const { if (dc) return dbus_connection_get_is_authenticated(dc); else return false; } void GMDBus::flush() { if (dc) dbus_connection_flush(dc); } FXString GMDBus::dbusversion() { #if (DBUSVERSION == MKDBUSVERSION(1,1,20)) || DBUSVERSION >= MKDBUSVERSION(1,2,0) int major,minor,micro; dbus_get_version(&major,&minor,µ); return GMStringFormat("%d.%d.%d",major,minor,micro); #else return FXString("1.0.x"); #endif } struct CallTarget{ FXObject * target; FXSelector message; }; static void fxdbus_pendingcallfree(void *memory){ //fxmessage("fxdbuspendingcallfree\n"); if (memory){ CallTarget * call = (CallTarget*)memory; delete call; } } static void fxdbus_pendingcallnotify(DBusPendingCall*pending,void*data){ DBusMessage * msg = dbus_pending_call_steal_reply(pending); if (msg) { CallTarget * call = (CallTarget*)data; if (call && call->target && call->message) { call->target->handle(NULL,FXSEL(SEL_COMMAND,call->message),msg); } dbus_message_unref(msg); } } FXbool GMDBus::sendWithReply(DBusMessage * msg,FXint timeout,FXObject*tgt,FXSelector sel){ FXASSERT(msg); DBusPendingCall * pending = NULL; if (dbus_connection_send_with_reply(dc,msg,&pending,timeout)) { if (pending) { CallTarget * call = new CallTarget; call->target=tgt; call->message=sel; dbus_pending_call_set_notify(pending,fxdbus_pendingcallnotify,(void*)call,fxdbus_pendingcallfree); dbus_pending_call_unref(pending); } dbus_message_unref(msg); return true; } return false; } void GMDBus::send(DBusMessage * msg){ FXuint serial; dbus_connection_send(dc,msg,&serial); dbus_message_unref(msg); } void GMDBus::send(DBusMessage * msg,FXuint & serial){ dbus_connection_send(dc,msg,&serial); dbus_message_unref(msg); } /*******************************************************************************************************/ /* MESSAGE HANDLERS */ /*******************************************************************************************************/ long GMDBus::onHandleRead(FXObject*,FXSelector,void*ptr){ #if FOXVERSION < FXVERSION(1,7,0) DBusWatch * watch = fxdbus.find((FXint)(FXival)ptr); #else DBusWatch * watch = reinterpret_cast(ptr); #endif dbus_watch_handle(watch,DBUS_WATCH_READABLE); FXApp::instance()->addChore(this,ID_DISPATCH); return 0; } long GMDBus::onHandleWrite(FXObject*,FXSelector,void*ptr){ #if FOXVERSION < FXVERSION(1,7,0) DBusWatch * watch = fxdbus.find((FXint)(FXival)ptr); #else DBusWatch * watch = reinterpret_cast(ptr); #endif dbus_watch_handle(watch,DBUS_WATCH_WRITABLE); return 0; } long GMDBus::onHandleExcept(FXObject*,FXSelector,void*ptr){ #if FOXVERSION < FXVERSION(1,7,0) DBusWatch * watch = fxdbus.find((FXint)(FXival)ptr); #else DBusWatch * watch = reinterpret_cast(ptr); #endif dbus_watch_handle(watch,DBUS_WATCH_ERROR|DBUS_WATCH_HANGUP); return 0; } long GMDBus::onDispatch(FXObject*,FXSelector,void*/*ptr*/){ if (dbus_connection_dispatch((DBusConnection*)dc)==DBUS_DISPATCH_DATA_REMAINS) { FXApp::instance()->addChore(this,ID_DISPATCH); } return 0; } /*******************************************************************************************************/ /* PROTECTED API */ /*******************************************************************************************************/ void GMDBus::setup_event_loop() { FXASSERT(dc); dbus_connection_set_watch_functions(dc, fxdbus_addwatch, fxdbus_removewatch, fxdbus_togglewatch, this,NULL); dbus_connection_set_timeout_functions(dc, fxdbus_addtimeout, fxdbus_removetimeout, fxdbus_toggletimeout, this,NULL); dbus_connection_set_wakeup_main_function(dc,fxdbus_wakeup,NULL,NULL); } static DBusHandlerResult dbus_proxy_filter(DBusConnection *,DBusMessage * msg,void * ptr){ GMDBusProxy * proxy = reinterpret_cast(ptr); FXASSERT(proxy); FXuint type = dbus_message_get_type(msg); if (type==DBUS_MESSAGE_TYPE_METHOD_CALL) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } else if (type==DBUS_MESSAGE_TYPE_METHOD_RETURN || type==DBUS_MESSAGE_TYPE_ERROR) { if (proxy->matchSerial(msg)) return DBUS_HANDLER_RESULT_HANDLED; else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } else { /* SIGNALS */ DEBUG_DBUS_MESSAGE(msg); if (dbus_message_has_path(msg,DBUS_PATH_DBUS)) { if (dbus_message_is_signal(msg,DBUS_INTERFACE_DBUS,"NameOwnerChanged")) { const FXchar * dbus_name=NULL; const FXchar * new_owner=NULL; const FXchar * old_owner=NULL; if (dbus_message_get_args(msg,NULL,DBUS_TYPE_STRING,&dbus_name,DBUS_TYPE_STRING,&old_owner,DBUS_TYPE_STRING,&new_owner,DBUS_TYPE_INVALID)) { if (compare(proxy->getName(),dbus_name)==0) { if (new_owner==NULL || compare(new_owner,"")==0) { proxy->handle(proxy,FXSEL(SEL_DESTROY,0),NULL); } else if (old_owner==NULL || compare(old_owner,"")==0){ proxy->handle(proxy,FXSEL(SEL_CREATE,0),NULL); } else { proxy->handle(proxy,FXSEL(SEL_REPLACED,0),NULL); } return DBUS_HANDLER_RESULT_HANDLED; } } } } /// Make sure it is for us... if (dbus_message_has_path(msg,proxy->getPath().text()) && dbus_message_has_interface(msg,proxy->getInterface().text())) { return proxy->handle(proxy,FXSEL(SEL_SIGNAL,0),msg) ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } FXDEFMAP(GMDBusProxy) GMDBusProxyMap[]={ FXMAPFUNC(SEL_CREATE, 0,GMDBusProxy::onCreate), FXMAPFUNC(SEL_DESTROY, 0,GMDBusProxy::onDestroy), FXMAPFUNC(SEL_REPLACED, 0,GMDBusProxy::onReplaced), FXMAPFUNC(SEL_SIGNAL, 0,GMDBusProxy::onSignal), FXMAPFUNC(SEL_COMMAND, 0,GMDBusProxy::onMethod), }; FXIMPLEMENT(GMDBusProxy,FXObject,GMDBusProxyMap,ARRAYNUMBER(GMDBusProxyMap)); GMDBusProxy::GMDBusProxy() : target(NULL) { } GMDBusProxy::~GMDBusProxy() { FXString rule = "type='signal',sender='"+ name +"',path='" + path +"',interface='"+interface+"'"; dbus_bus_remove_match(bus->connection(),rule.text(),NULL); dbus_connection_remove_filter(bus->connection(),dbus_proxy_filter,this); } GMDBusProxy::GMDBusProxy(GMDBus *c,const FXchar * n,const FXchar * p,const FXchar * i) : bus(c),name(n),path(p),interface(i),associated(true),target(NULL) { FXString rule = "type='signal',sender='"+ name +"',path='" + path +"',interface='"+interface+"'"; dbus_bus_add_match(bus->connection(),rule.text(),NULL); dbus_connection_add_filter(bus->connection(),dbus_proxy_filter,this,NULL); } struct GMDBusProxyReply { FXObject * target; FXSelector message; GMDBusProxyReply(FXObject * t,FXSelector m) : target(t), message(m) {} }; FXbool GMDBusProxy::matchSerial(DBusMessage * msg) { void * ptr; FXuint s=dbus_message_get_reply_serial(msg); if (s && (ptr=serial.find((void*)(FXuval)s))!=NULL) { GMDBusProxyReply * reply = reinterpret_cast(ptr); if (reply->target) reply->target->handle(this,FXSEL(SEL_COMMAND,reply->message),msg); serial.remove((void*)(FXuval)dbus_message_get_reply_serial(msg)); delete reply; return true; } else { return false; } } void GMDBusProxy::send(DBusMessage*msg,FXObject * obj,FXSelector m) { FXuint s; dbus_connection_send(bus->connection(),msg,&s); dbus_message_unref(msg); serial.insert((void*)(FXuval)s,new GMDBusProxyReply(obj,m)); } DBusMessage * GMDBusProxy::method(const FXchar * method){ return dbus_message_new_method_call(name.text(),path.text(),interface.text(),method); } long GMDBusProxy::onCreate(FXObject*,FXSelector,void*ptr) { associated=true; return target && target->tryHandle(this,FXSEL(SEL_DESTROY,message),ptr); } long GMDBusProxy::onDestroy(FXObject*,FXSelector,void*ptr) { associated=false; return target && target->tryHandle(this,FXSEL(SEL_DESTROY,message),ptr); } long GMDBusProxy::onReplaced(FXObject*,FXSelector,void*ptr) { return target && target->tryHandle(this,FXSEL(SEL_REPLACED,message),ptr); } long GMDBusProxy::onSignal(FXObject*,FXSelector,void*ptr) { return target && target->tryHandle(this,FXSEL(SEL_SIGNAL,message),ptr); } long GMDBusProxy::onMethod(FXObject*,FXSelector,void*ptr) { return target && target->tryHandle(this,FXSEL(SEL_COMMAND,message),ptr); } /*******************************************************************************************************/ /* HELPER API */ /*******************************************************************************************************/ void gm_dbus_variant_append_basic(DBusMessageIter * iter,const FXchar * element_type_string,FXint element_type,const void * value) { DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_VARIANT,element_type_string,&container); dbus_message_iter_append_basic(&container,element_type,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_variant_append_string(DBusMessageIter * iter,const FXchar * value) { gm_dbus_variant_append_basic(iter,DBUS_TYPE_STRING_AS_STRING,DBUS_TYPE_STRING,&value); } void gm_dbus_variant_append_int32(DBusMessageIter * iter,const FXint value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_INT32_AS_STRING,DBUS_TYPE_INT32,&value); } void gm_dbus_variant_append_uint32(DBusMessageIter * iter,const FXuint value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_UINT32_AS_STRING,DBUS_TYPE_UINT32,&value); } void gm_dbus_variant_append_path(DBusMessageIter * iter,const FXchar * value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_OBJECT_PATH_AS_STRING,DBUS_TYPE_OBJECT_PATH,&value); } void gm_dbus_variant_append_bool(DBusMessageIter * iter,const dbus_bool_t value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_BOOLEAN_AS_STRING,DBUS_TYPE_BOOLEAN,&value); } void gm_dbus_variant_append_double(DBusMessageIter * iter,const FXdouble value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_DOUBLE_AS_STRING,DBUS_TYPE_DOUBLE,&value); } void gm_dbus_variant_append_long(DBusMessageIter * iter,const FXlong value){ gm_dbus_variant_append_basic(iter,DBUS_TYPE_INT64_AS_STRING,DBUS_TYPE_INT64,&value); } void gm_dbus_variant_append_string_list(DBusMessageIter * iter,const FXchar * value[]){ DBusMessageIter container; DBusMessageIter array; dbus_message_iter_open_container(iter,DBUS_TYPE_VARIANT,DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,&container); dbus_message_iter_open_container(&container,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array); for (FXint n=0;value[n];n++) { dbus_message_iter_append_basic(&array,DBUS_TYPE_STRING,&value[n]); } dbus_message_iter_close_container(&container,&array); dbus_message_iter_close_container(iter,&container); } void gm_dbus_variant_append_string_list(DBusMessageIter * iter,const FXStringList & list){ DBusMessageIter container; DBusMessageIter array; dbus_message_iter_open_container(iter,DBUS_TYPE_VARIANT,DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,&container); dbus_message_iter_open_container(&container,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array); for (FXint n=0;list.no();n++) { dbus_message_iter_append_basic(&array,DBUS_TYPE_STRING,list[n].text()); } dbus_message_iter_close_container(&container,&array); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_int32(DBusMessageIter * iter,const FXchar * key,const FXint value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_int32(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_uint32(DBusMessageIter * iter,const FXchar * key,const FXuint value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_uint32(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_string(DBusMessageIter * iter,const FXchar * key,const FXchar * value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_string(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_string(DBusMessageIter * iter,const FXchar * key,const FXString & value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_string(&container,value.text()); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_path(DBusMessageIter * iter,const FXchar * key,const FXchar * value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_path(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_bool(DBusMessageIter * iter,const FXchar * key,const dbus_bool_t value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_bool(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_double(DBusMessageIter * iter,const FXchar * key,const FXdouble & value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_double(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_long(DBusMessageIter * iter,const FXchar * key,const FXlong & value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_long(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_string_list(DBusMessageIter * iter,const FXchar * key,const FXchar * value[]){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_string_list(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_dict_append_string_list(DBusMessageIter * iter,const FXchar * key,const FXStringList &value){ DBusMessageIter container; dbus_message_iter_open_container(iter,DBUS_TYPE_DICT_ENTRY,0,&container); dbus_message_iter_append_basic(&container,DBUS_TYPE_STRING,&key); gm_dbus_variant_append_string_list(&container,value); dbus_message_iter_close_container(iter,&container); } void gm_dbus_append_string(DBusMessageIter *iter,const FXString & value){ const FXchar * v = value.text(); dbus_message_iter_append_basic(iter,DBUS_TYPE_STRING,&v); } void gm_dbus_append_string_pair(DBusMessageIter *iter,const FXchar * key,const FXchar * value){ dbus_message_iter_append_basic(iter,DBUS_TYPE_STRING,&key); dbus_message_iter_append_basic(iter,DBUS_TYPE_STRING,&value); } DBusHandlerResult gm_dbus_reply_string(DBusConnection * connection,DBusMessage * msg,const FXchar * data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_STRING,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_uint_string(DBusConnection * connection,DBusMessage * msg,const FXuint val,const FXchar * data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_UINT32,&val,DBUS_TYPE_STRING,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_int(DBusConnection * connection,DBusMessage * msg,const FXint data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_INT32,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_double(DBusConnection * connection,DBusMessage * msg,const FXdouble data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_DOUBLE,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_long(DBusConnection * connection,DBusMessage * msg,const FXlong data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_INT64,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_unsigned_int(DBusConnection * connection,DBusMessage * msg,const FXuint data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_UINT32,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_bool(DBusConnection * connection,DBusMessage * msg,const dbus_bool_t data) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_message_append_args(reply,DBUS_TYPE_BOOLEAN,&data,DBUS_TYPE_INVALID); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_string_list(DBusConnection * connection,DBusMessage * msg,const FXchar * data[]) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { DBusMessageIter iter; DBusMessageIter array; dbus_message_iter_init_append(reply,&iter); dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array); for (FXint n=0;data[n];n++) { dbus_message_iter_append_basic(&array,DBUS_TYPE_STRING,&data[n]); } dbus_message_iter_close_container(&iter,&array); dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult gm_dbus_reply_if_needed(DBusConnection * connection,DBusMessage * msg) { if (!dbus_message_get_no_reply(msg)) { FXuint serial; DBusMessage * reply = dbus_message_new_method_return(msg); if (reply) { dbus_connection_send(connection,reply,&serial); dbus_message_unref(reply); } } return DBUS_HANDLER_RESULT_HANDLED; } void gm_dbus_match_signal(DBusConnection*connection,const FXchar * path,const FXchar * interface,const FXchar * member){ FXString rule = GMStringFormat("type='signal',path='%s',interface='%s',member='%s'",path,interface,member); dbus_bus_add_match(connection,rule.text(),NULL); } gogglesmm-0.12.7/src/GMPreferences.h0000644000175000001440000001107411644100363015733 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMPREFERENCES_H #define GMPREFERENCES_H enum { STARTUP_MAINWINDOW = 0, STARTUP_REMOTE, STARTUP_LAST }; enum { REPLAYGAIN_OFF=0, REPLAYGAIN_TRACK=1, REPLAYGAIN_ALBUM=2 }; struct ColorTheme { const FXchar* name; FXColor base; FXColor border; FXColor back; FXColor altback; FXColor fore; FXColor selback; FXColor selfore; FXColor tipback; FXColor tipfore; FXColor menuback; FXColor menufore; FXColor playfore; FXColor playback; FXColor hilite; FXColor shadow; FXColor trayback; ColorTheme(); ColorTheme(const FXchar * _name,FXColor _base,FXColor _border,FXColor _back,FXColor _altback,FXColor _fore,FXColor _selback,FXColor _selfore,FXColor _tipback,FXColor _tipfore,FXColor _psback=FXRGB(210,230,210),FXColor _psfore=FXRGB( 0, 0, 0)); void save() const; friend bool operator==(const ColorTheme& t1,const ColorTheme& t2); }; class GMImportOptions { public: FXString default_field; FXString exclude_folder; FXString exclude_file; FXString filename_template; FXbool track_from_filelist; FXbool replace_underscores; FXuint parse_method; public: enum { PARSE_TAG = 0, PARSE_FILENAME = 1, PARSE_BOTH = 2 }; public: GMImportOptions(); /// Save to FXSettings void save(FXSettings & settings) const; /// Load from FXSettings void load(FXSettings & settings); }; class GMSyncOptions { public: FXbool import_new; FXbool remove_missing; FXbool remove_all; FXbool update; FXbool update_always; public: GMSyncOptions(); /// Save to FXSettings void save(FXSettings & settings) const; /// Load from FXSettings void load(FXSettings & settings); }; class GMPreferences { public: GMImportOptions import; GMSyncOptions sync; FXStringList gui_sort_keywords; FXString export_format_template; FXString export_character_filter; FXString gui_format_title; FXbool gui_show_status_bar; FXbool gui_hide_player_when_close; FXbool gui_toolbar_bigicons; FXbool gui_toolbar_docktop; FXbool gui_toolbar_showlabels; FXbool gui_show_browser_icons; FXbool gui_show_playing_albumcover; FXbool gui_show_albumcovers; FXbool gui_tray_icon; FXbool gui_tray_icon_disabled; FXbool gui_show_playing_titlebar; FXbool gui_show_opengl_coverview; FXColor gui_row_color; FXColor gui_play_color; FXColor gui_playtext_color; FXColor gui_tray_color; FXint gui_coverdisplay_size; FXint play_replaygain; FXuint play_repeat; FXbool play_close_stream; FXbool play_pause_close_device; FXbool play_gapless; FXbool play_shuffle; FXbool play_open_device_on_startup; FXuint export_encoding; FXbool export_lowercase; FXbool export_lowercase_extension; FXbool export_underscore; FXbool dbus_notify_daemon; public: /// Default Constructor GMPreferences(); GMPreferences(const GMPreferences & p); void parseCommandLine(int argc,char **argv); void resetColors(); /// Set Key Words void setKeyWords(const FXString & keywords); void getKeyWords(FXString & keywords) const; /// Save to FXSettings void save(FXSettings & settings) const; /// Load from FXSettings void load(FXSettings & settings); }; #endif gogglesmm-0.12.7/src/GMPreferencesDialog.cpp0000644000175000001440000015254511667301260017423 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "icons.h" #include #include #include "GMPlayer.h" #include "GMWindow.h" #include "GMTrackList.h" #include "GMList.h" #include "GMRemote.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMDatabaseSource.h" #include "GMTrackView.h" #include "GMSourceView.h" #include "GMAudioScrobbler.h" #include "GMIconTheme.h" #include "GMPreferencesDialog.h" #include "GMApp.h" #include "GMTrayIcon.h" #include "GMImageView.h" #include "GMFontDialog.h" ColorTheme::ColorTheme() { base = FXApp::instance()->getBaseColor(); border = FXApp::instance()->getBorderColor(); back = FXApp::instance()->getBackColor(); fore = FXApp::instance()->getForeColor(); selfore = FXApp::instance()->getSelforeColor(); selback = FXApp::instance()->getSelbackColor(); tipfore = FXApp::instance()->getTipforeColor(); tipback = FXApp::instance()->getTipbackColor(); menufore = FXApp::instance()->getSelMenuTextColor(); menuback = FXApp::instance()->getSelMenuBackColor(); shadow = FXApp::instance()->getShadowColor(); hilite = FXApp::instance()->getHiliteColor(); playfore = GMPlayerManager::instance()->getPreferences().gui_playtext_color; playback = GMPlayerManager::instance()->getPreferences().gui_play_color; altback = GMPlayerManager::instance()->getPreferences().gui_row_color; trayback = GMPlayerManager::instance()->getPreferences().gui_tray_color; } ColorTheme::ColorTheme(const FXchar * _name,FXColor _base,FXColor _border,FXColor _back,FXColor _altback,FXColor _fore,FXColor _selback,FXColor _selfore,FXColor _tipback,FXColor _tipfore,FXColor _psback,FXColor _psfore) : name(_name), base(_base), border(_border), back(_back), altback(_altback), fore(_fore), selback(_selback), selfore(_selfore), tipback(_tipback), tipfore(_tipfore), menuback(_selback), menufore(_selfore), playfore(_psfore), playback(_psback), hilite(makeHiliteColor(base)), shadow(makeShadowColor(base)), trayback(_base) { } void ColorTheme::save() const { FXApp::instance()->setBaseColor(base); FXApp::instance()->setBorderColor(border); FXApp::instance()->setBackColor(back); FXApp::instance()->setForeColor(fore); FXApp::instance()->setSelbackColor(selback); FXApp::instance()->setSelforeColor(selfore); FXApp::instance()->setTipbackColor(tipback); FXApp::instance()->setTipforeColor(tipfore); FXApp::instance()->setSelMenuBackColor(menuback); FXApp::instance()->setSelMenuTextColor(menufore); FXApp::instance()->setShadowColor(shadow); FXApp::instance()->setHiliteColor(hilite); GMPlayerManager::instance()->getPreferences().gui_playtext_color=playfore; GMPlayerManager::instance()->getPreferences().gui_play_color=playback; GMPlayerManager::instance()->getPreferences().gui_row_color=altback; GMPlayerManager::instance()->getPreferences().gui_tray_color=trayback; } bool operator==(const ColorTheme& t1,const ColorTheme& t2) { return (t1.base==t2.base && t1.border==t2.border && t1.back==t2.back && t1.altback==t2.altback && t1.fore==t2.fore && t1.selback==t2.selback && t1.selfore==t2.selfore && t1.tipback==t2.tipback && t1.tipfore==t2.tipfore && t1.menuback==t2.menuback && t1.menufore==t2.menufore && t1.playfore==t2.playfore && t1.playback==t2.playback && t1.hilite==t2.hilite && t1.shadow==t2.shadow //&& // t1.trayback==t2.trayback ); } /// Think you have a great color theme, mail them to s.jansen@gmail.com const ColorTheme ColorThemes[]={ ColorTheme("FOX", // name FXRGB(212,208,200), // base FXRGB( 0, 0, 0), // boder FXRGB(255,255,255), // back FXRGB(240,240,240), // alt back FXRGB( 0, 0, 0), // fore FXRGB( 10, 36,106), // selback FXRGB(255,255,255), // selfore FXRGB(255,255,225), // tipback FXRGB(0,0,0)), // tipfore ColorTheme("Clearlooks" , // name FXRGB(237,236,235), // base FXRGB( 0, 0, 0), // boder FXRGB(255,255,255), // back FXRGB(240,240,240), // alt back FXRGB( 26, 26, 25), // fore FXRGB(134,171,217), // selback FXRGB(255,255,255), // selfore FXRGB(245,245,181), // tipback FXRGB( 0, 0, 0)), // tipfore ColorTheme("Honeycomb" , // name FXRGB(213,215,209), // base FXRGB( 0, 0, 0), // boder FXRGB(255,255,255), // back FXRGB(238,238,238), // alt back FXRGB( 0, 0, 0), // fore FXRGB(227,167, 0), // selback FXRGB(255,255,255), // selfore FXRGB(255,242,153), // tipback FXRGB( 64, 48, 0)), // tipfore ColorTheme("Norway" , // name FXRGB(235,226,210), // base FXRGB( 0, 0, 0), // boder FXRGB(253,252,251), // back FXRGB(238,238,238), // alt back FXRGB( 0, 0, 0), // fore FXRGB( 29,135,205), // selback FXRGB(255,255,255), // selfore FXRGB(253,252,251), // tipback FXRGB( 0, 0, 0)), // tipfore ColorTheme("Oxygen" , // name FXRGB(224,223,223), // base FXRGB( 0, 0, 0), // boder FXRGB(255,255,255), // back FXRGB(238,238,238), // alt back FXRGB( 20, 19, 18), // fore FXRGB( 65,141,212), // selback FXRGB(255,255,255), // selfore FXRGB(192,218,255), // tipback FXRGB( 20, 19, 18)), // tipfore ColorTheme("Obsidian Coast" , // name FXRGB( 48, 47, 47), // base FXRGB( 0, 0, 0), // boder FXRGB( 32, 31, 31), // back FXRGB( 38, 38, 38), // alt back FXRGB(224,223,220), // fore FXRGB( 24,72,128), // selback FXRGB(255,255,255), // selfore FXRGB( 16, 48, 80), // tipback FXRGB(196,209,224),// tipfore FXRGB(24,128,73), // psback FXRGB(224,223,220)), // psfore ColorTheme("Steel" , // name FXRGB(224,223,216), // base FXRGB( 0, 0, 0), // boder FXRGB(255,255,255), // back FXRGB(238,238,238), // alt back FXRGB( 0, 0, 0), // fore FXRGB(123,161,173), // selback FXRGB(255,255,255), // selfore FXRGB(220,231,235), // tipback FXRGB( 37, 34, 28)), // tipfore ColorTheme("Wonton Soup" , // name FXRGB (71, 76, 86), // base FXRGB( 0, 0, 0), // boder FXRGB( 58, 62, 70), // back FXRGB( 62, 66, 75), // alt back FXRGB(182,193,208), // fore FXRGB(117,133,153), // selback FXRGB(209,225,244), // selfore FXRGB(182,193,208), // tipback FXRGB(42,44,48), // tipfore FXRGB(134,147,134), // psback FXRGB(209,225,244)),// psfore }; FXDEFMAP(GMPreferencesDialog) GMPreferencesDialogMap[]={ FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_SCROBBLE,GMPreferencesDialog::onCmdLastFMScrobble), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_SERVICE,GMPreferencesDialog::onCmdLastFMService), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_USERNAME,GMPreferencesDialog::onCmdLastFMUserName), FXMAPFUNC(SEL_CHANGED,GMPreferencesDialog::ID_LASTFM_USERNAME,GMPreferencesDialog::onCmdLastFMUserName), FXMAPFUNC(SEL_FOCUSIN,GMPreferencesDialog::ID_LASTFM_PASSWORD,GMPreferencesDialog::onFocusLastFMPassWord), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_PASSWORD,GMPreferencesDialog::onCmdLastFMPassWord), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_LASTFM_JOIN,GMPreferencesDialog::onCmdLastFMJoin), FXMAPFUNCS(SEL_COMMAND,GMPreferencesDialog::ID_BASE_COLOR,GMPreferencesDialog::ID_BORDER_COLOR,GMPreferencesDialog::onCmdElementColor), FXMAPFUNCS(SEL_UPDATE,GMPreferencesDialog::ID_BASE_COLOR,GMPreferencesDialog::ID_BORDER_COLOR,GMPreferencesDialog::onUpdElementColor), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_COLOR_THEME,GMPreferencesDialog::onCmdColorTheme), FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_COLOR_THEME,GMPreferencesDialog::onUpdColorTheme), FXMAPFUNC(SEL_UPDATE,GMPreferencesDialog::ID_FONT,GMPreferencesDialog::onUpdFont), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_CHANGE_FONT,GMPreferencesDialog::onCmdChangeFont), FXMAPFUNC(SEL_COMMAND,FXDialogBox::ID_ACCEPT,GMPreferencesDialog::onCmdAccept), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_AUDIO_DRIVER,GMPreferencesDialog::onCmdAudioDriver), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_REPLAY_GAIN,GMPreferencesDialog::onCmdReplayGain), FXMAPFUNC(SEL_COMMAND,GMPreferencesDialog::ID_ICON_THEME,GMPreferencesDialog::onCmdIconTheme) }; FXIMPLEMENT(GMPreferencesDialog,FXDialogBox,GMPreferencesDialogMap,ARRAYNUMBER(GMPreferencesDialogMap)) GMPreferencesDialog::GMPreferencesDialog(FXWindow * p) : FXDialogBox(p,FXString::null,DECOR_BORDER|DECOR_TITLE,0,0,0,0,0,0,0,0,0,0), password_set(false) { setTitle(tr("Preferences")); target_closeishide.connect(GMPlayerManager::instance()->getPreferences().gui_hide_player_when_close); target_keywords.connect(keywords); target_close_audio.connect(GMPlayerManager::instance()->getPreferences().play_close_stream); target_pause_close_device.connect(GMPlayerManager::instance()->getPreferences().play_pause_close_device); target_gapless.connect(GMPlayerManager::instance()->getPreferences().play_gapless); target_open_device_on_startup.connect(GMPlayerManager::instance()->getPreferences().play_open_device_on_startup); target_show_playing_albumcover.connect(GMPlayerManager::instance()->getPreferences().gui_show_playing_albumcover); target_show_albumcovers.connect(GMPlayerManager::instance()->getPreferences().gui_show_albumcovers); #ifdef HAVE_DBUS target_dbus_notify_daemon.connect(GMPlayerManager::instance()->getPreferences().dbus_notify_daemon); #endif target_gui_tray_icon.connect(GMPlayerManager::instance()->getPreferences().gui_tray_icon); target_replaygain.connect(GMPlayerManager::instance()->getPreferences().play_replaygain,this,ID_REPLAY_GAIN); target_gui_format_title.connect(GMPlayerManager::instance()->getPreferences().gui_format_title); target_gui_show_playing_titlebar.connect(GMPlayerManager::instance()->getPreferences().gui_show_playing_titlebar); GMPlayerManager::instance()->getPlayer()->checkInitialized(); GMPlayerManager::instance()->getPreferences().getKeyWords(keywords); const FXuint labelstyle=LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT; const FXuint textfieldstyle=TEXTFIELD_ENTER_ONLY|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN; FXGroupBox * grpbox; FXMatrix * matrix; FXVerticalFrame * vframe; FXVerticalFrame * vframe2; FXVerticalFrame * main=new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y); GMTabBook * tabbook=new GMTabBook(main,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,0,0,0,0); new GMTabItem(tabbook,tr("&General"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Sort Options"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); new FXLabel(matrix,tr("Ignore leading words"),NULL,labelstyle); new GMTextField(matrix,10,&target_keywords,FXDataTarget::ID_VALUE,textfieldstyle); grpbox = new FXGroupBox(vframe,tr("Album Covers"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); new GMCheckButton(grpbox,tr("Show album cover of playing track\tShow album cover of playing track"),&target_show_playing_albumcover,FXDataTarget::ID_VALUE); new GMCheckButton(grpbox,tr("Show album covers in album browser\tShow album covers in album browser"),&target_show_albumcovers,FXDataTarget::ID_VALUE); grpbox = new FXGroupBox(vframe,tr("System Tray"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); if (!GMPlayerManager::instance()->getPreferences().gui_tray_icon_disabled) new GMCheckButton(grpbox,tr("Show Tray Icon\tShow tray icon in the system tray."),&target_gui_tray_icon,FXDataTarget::ID_VALUE); #ifdef HAVE_DBUS if (GMPlayerManager::instance()->hasSessionBus()) { new GMCheckButton(grpbox,tr("Show Track Change Notifications\tInform notification daemon of track changes."),&target_dbus_notify_daemon,FXDataTarget::ID_VALUE); } #endif grpbox = new FXGroupBox(vframe,tr("Last.fm"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,23,3,0,0,0,0); grpbox->setFont(GMApp::instance()->getThickFont()); if (GMPlayerManager::instance()->getAudioScrobbler()->isBanned()) { new FXLabel(grpbox,tr("This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM."),NULL,JUSTIFY_LEFT); } else { matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0); new FXLabel(matrix,tr("Service:"),NULL,labelstyle); FXHorizontalFrame * hframe = new FXHorizontalFrame(matrix,FRAME_NONE,0,0,0,0,0,0,0,0); FXuint current_service = GMPlayerManager::instance()->getAudioScrobbler()->getService(); lastfm_service = new GMListBox(hframe,this,ID_LASTFM_SERVICE,FRAME_SUNKEN|FRAME_THICK); lastfm_service->appendItem("Last.fm"); lastfm_service->appendItem("Libre.fm"); if (current_service==SERVICE_CUSTOM) { lastfm_service->appendItem("Custom"); lastfm_service->setNumVisible(3); } else { lastfm_service->setNumVisible(2); } lastfm_service->setCurrentItem(current_service); lastfm_join = new FXButton(hframe,tr("&Sign up…"),NULL,this,ID_LASTFM_JOIN,ICON_AFTER_TEXT|FRAME_RAISED|JUSTIFY_CENTER_Y|JUSTIFY_LEFT|BUTTON_TOOLBAR,0,0,0,0,7); lastfm_join->setTextColor(FXRGB(0,0,255)); lastfm_join->setDefaultCursor(GMIconTheme::instance()->cursor_hand); if (current_service==SERVICE_CUSTOM) lastfm_join->hide(); lastfm_username_label = new FXLabel(matrix,tr("Username:"),NULL,labelstyle); lastfm_username = new GMTextField(matrix,20,this,ID_LASTFM_USERNAME,FRAME_SUNKEN|FRAME_THICK); lastfm_password_label = new FXLabel(matrix,tr("Password:"),NULL,labelstyle); lastfm_password = new GMTextField(matrix,20,this,ID_LASTFM_PASSWORD,FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_PASSWD); new FXFrame(matrix,FRAME_NONE); lastfm_scrobble = new GMCheckButton(grpbox,tr("Scrobble"),this,ID_LASTFM_SCROBBLE,LAYOUT_FIX_X|LAYOUT_FIX_Y|CHECKBUTTON_NORMAL,6,0); lastfm_scrobble->setFont(GMApp::instance()->getThickFont()); lastfm_username->setText(GMPlayerManager::instance()->getAudioScrobbler()->getUsername()); if (GMPlayerManager::instance()->getAudioScrobbler()->hasPassword()) lastfm_password->setText("1234567890"); lastfm_scrobble->setCheck(GMPlayerManager::instance()->getAudioScrobbler()->isEnabled()); if (current_service==SERVICE_LASTFM){ lastfm_username->hide(); lastfm_username_label->hide(); lastfm_password->hide(); lastfm_password_label->hide(); } else { lastfm_username->show(); lastfm_username_label->show(); lastfm_password->show(); lastfm_password_label->show(); } } new GMTabItem(tabbook,tr("&Window"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Window"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); new GMCheckButton(grpbox,tr("Close button minimizes to tray"),&target_closeishide,FXDataTarget::ID_VALUE); statusbarbutton = new GMCheckButton(grpbox,tr("Show Status Bar"),NULL,0); statusbarbutton->setCheck(GMPlayerManager::instance()->getPreferences().gui_show_status_bar); browser_icons = new GMCheckButton(grpbox,tr("Show Icons in Track Browser"),NULL,0); browser_icons->setCheck(GMPlayerManager::instance()->getPreferences().gui_show_browser_icons); new GMCheckButton(grpbox,tr("Display playing track in title bar"),&target_gui_show_playing_titlebar,FXDataTarget::ID_VALUE); grpbox = new FXGroupBox(vframe,tr("Player Controls"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS); new FXLabel(matrix,tr("Location:"),NULL,labelstyle); toolbar_docktop = new GMListBox(matrix,NULL,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X); toolbar_docktop->appendItem(tr("Top")); toolbar_docktop->appendItem(tr("Bottom")); toolbar_docktop->setNumVisible(2); if (GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop) toolbar_docktop->setCurrentItem(0); else toolbar_docktop->setCurrentItem(1); new FXLabel(matrix,tr("Title Format:"),NULL,labelstyle); new GMTextField(matrix,20,&target_gui_format_title,FXDataTarget::ID_VALUE,TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X); new FXLabel(matrix,tr("Style:"),NULL,labelstyle); toolbar_showlabels = new GMCheckButton(matrix,tr("Show Labels"),NULL,0); toolbar_showlabels->setCheck(GMPlayerManager::instance()->getPreferences().gui_toolbar_showlabels); new FXFrame(matrix,FRAME_NONE); toolbar_bigicons = new GMCheckButton(matrix,tr("Large Icons"),NULL,0); toolbar_bigicons->setCheck(GMPlayerManager::instance()->getPreferences().gui_toolbar_bigicons); new GMTabItem(tabbook,tr("A&ppearance"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Colors"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,2,2,0,2); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,6,MATRIX_BY_COLUMNS|LAYOUT_SIDE_LEFT,0,0,0,0,0,0,0,0,0,0); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("fg\tForeground Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X); new FXLabel(matrix,tr("bg\tBackground Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X); new FXLabel(matrix,tr("alt bg\tAlternative Background Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_CENTER_X); new FXFrame(matrix,FRAME_NONE); new FXFrame(matrix,FRAME_NONE); new FXFrame(matrix,FRAME_NONE); new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X); new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X); new FXSeparator(matrix,SEPARATOR_LINE|LAYOUT_FILL_X); new FXFrame(matrix,FRAME_NONE); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("Normal\tNormal Text Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_ALTERNATIVE_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXLabel(matrix,tr("Base\tBase Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_BASE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXLabel(matrix,tr("Selected\tSelected Text Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_SEL_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_SEL_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("Border\tBorder Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_BORDER_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); // new FXLabel(matrix,tr("Menu\tMenu Base Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); // new FXColorWell(matrix,0,this,ID_MENU_BASE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXLabel(matrix,tr("Menu\tMenu Text Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_MENU_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_MENU_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("Hilite\tHilite Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_HILITE_COLOR,COLORWELL_OPAQUEONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXLabel(matrix,tr("Tooltip\tTooltip Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_TIP_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_TIP_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("Shadow\tShadow Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_SHADOW_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXLabel(matrix,tr("Playing\tPlaying Track Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_PLAY_FORE_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXColorWell(matrix,0,this,ID_PLAY_BACK_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXFrame(matrix,FRAME_NONE); new FXLabel(matrix,tr("Tray\tTray Background Color"),NULL,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT); new FXColorWell(matrix,0,this,ID_TRAY_COLOR,COLORWELL_OPAQUEONLY|FRAME_LINE|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_ROW|LAYOUT_CENTER_Y,0,0,40,24); new FXSeparator(grpbox,SEPARATOR_GROOVE|LAYOUT_FILL_Y|LAYOUT_SIDE_LEFT); vframe2 = new FXVerticalFrame(grpbox,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); new FXLabel(vframe2,tr("Presets:")); GMScrollFrame * sunken = new GMScrollFrame(vframe2); colorpresets = new GMList(sunken,this,ID_COLOR_THEME,LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y); colorpresets->setNumVisible(9); colorpresets->setScrollStyle(HSCROLLING_OFF); initColorThemes(); grpbox = new FXGroupBox(vframe,tr("Font & Icons"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,3,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,20); new FXLabel(matrix,tr("Default Font"),NULL,LAYOUT_RIGHT|LAYOUT_CENTER_Y); new GMTextField(matrix,20,this,ID_FONT,LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|TEXTFIELD_NORMAL|TEXTFIELD_READONLY); new GMButton(matrix,tr("Change…"),NULL,this,ID_CHANGE_FONT,BUTTON_NORMAL|LAYOUT_CENTER_Y); new FXLabel(matrix,tr("Icons"),NULL,LAYOUT_RIGHT|LAYOUT_CENTER_Y); // if (GMIconTheme::instance()->getNumThemes()==0) // GMIconTheme::instance()->listThemes(); themelist = new GMListBox(matrix,this,ID_ICON_THEME,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X); for (FXint i=0;igetNumThemes();i++) { themelist->appendItem(GMIconTheme::instance()->getThemeName(i),NULL,(void*)(FXival)i); } themelist->setSortFunc(FXList::ascending); themelist->sortItems(); themelist->setNumVisible(FXMIN(9,themelist->getNumItems())); for (FXint i=0;igetNumItems();i++) { if (GMIconTheme::instance()->getCurrentTheme()==(FXint)(FXival)themelist->getItemData(i)) { themelist->setCurrentItem(i); break; } } new GMTabItem(tabbook,tr("&Audio"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Engine"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP,0,0,0,0,0,0,0,0); new FXLabel(matrix,tr("Audio Driver:"),NULL,labelstyle); driverlist = new GMListBox(matrix,this,ID_AUDIO_DRIVER); FXString available,current; GMPlayerManager::instance()->getPlayer()->getAvailableDrivers(available); GMPlayerManager::instance()->getPlayer()->getCurrentDriver(current); driverlist->clearItems(); driverlist->fillItems(available); driverlist->setCurrentItem(driverlist->findItem(current)); driverlist->setNumVisible(FXMIN(9,driverlist->getNumItems())); new GMCheckButton(grpbox,tr("Close audio device on pause."),&target_pause_close_device,FXDataTarget::ID_VALUE); new GMCheckButton(grpbox,tr("Turn off playback engine on stop."),&target_close_audio,FXDataTarget::ID_VALUE); new GMCheckButton(grpbox,tr("Turn on playback engine on startup.\tFor faster startup, playback engine is normally started when first track is played.\tFor faster startup, playback engine is normally started when first track is played."),&target_open_device_on_startup,FXDataTarget::ID_VALUE); grpbox = new FXGroupBox(vframe,tr("Playback"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP,0,0,0,0,0,0,0,0); new FXLabel(matrix,tr("Replay Gain:"),NULL,labelstyle); GMListBox * gainlist = new GMListBox(matrix,&target_replaygain,FXDataTarget::ID_VALUE); gainlist->appendItem(tr("Off")); gainlist->appendItem(tr("Track")); gainlist->appendItem(tr("Album")); gainlist->setNumVisible(3); new GMCheckButton(grpbox,tr("Gapless playback"),&target_gapless,FXDataTarget::ID_VALUE); check_audio_normalization = new GMCheckButton(grpbox,tr("Volume Normalization")); if (GMPlayerManager::instance()->getPlayer()->hasVolumeNormalization() && GMPlayerManager::instance()->getPlayer()->getVolumeNormalization()) check_audio_normalization->setCheck(true); FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0); new GMButton(closebox,tr("&Close"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); } GMPreferencesDialog::~GMPreferencesDialog(){ } void GMPreferencesDialog::redraw(){ register FXWindow *w=GMPlayerManager::instance()->getMainWindow(); while(w){ w->recalc(); w->update(); if(w->getFirst()){ w=w->getFirst(); continue; } while(!w->getNext() && w->getParent()){ w=w->getParent(); } w=w->getNext(); } } long GMPreferencesDialog::onCmdAudioDriver(FXObject*,FXSelector,void*){ FXString selected=driverlist->getItemText(driverlist->getCurrentItem()); FXString current; FXString available; /// Stop Playback GMPlayerManager::instance()->stop(); if (!GMPlayerManager::instance()->getPlayer()->changeDriver(selected)) { //FXMessageBox::error(this,MBOX_OK,"Audio Device Error","Failed to open requested audio driver: %s",selected.text()); driverlist->disable(); } else { GMPlayerManager::instance()->getPlayer()->getCurrentDriver(current); if (selected!=current) { FXMessageBox::error(this,MBOX_OK,tr("Audio Device Error"),fxtrformat("Failed to open requested audio driver: %s"),selected.text()); } GMPlayerManager::instance()->getPlayer()->getAvailableDrivers(available); driverlist->clearItems(); driverlist->fillItems(available); driverlist->setCurrentItem(driverlist->findItem(current)); driverlist->setNumVisible(FXMIN(9,driverlist->getNumItems())); } return 1; } long GMPreferencesDialog::onCmdReplayGain(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->update_replay_gain(); return 1; } long GMPreferencesDialog::onCmdAccept(FXObject*,FXSelector,void*) { getApp()->stopModal(this,TRUE); hide(); GMWindow * mainwindow = GMPlayerManager::instance()->getMainWindow(); if (!GMPlayerManager::instance()->getAudioScrobbler()->isBanned() && password_set) { GMPlayerManager::instance()->getAudioScrobbler()->login(lastfm_username->getText(),lastfm_password->getText()); } GMPlayerManager::instance()->getPreferences().setKeyWords(keywords); if (check_audio_normalization->getCheck()) { GMPlayerManager::instance()->getPlayer()->setVolumeNormalization(true); } else { GMPlayerManager::instance()->getPlayer()->setVolumeNormalization(false); } GMPlayerManager::instance()->getPlayer()->setupGapless(); if (browser_icons->getCheck()!=GMPlayerManager::instance()->getPreferences().gui_show_browser_icons){ GMPlayerManager::instance()->getPreferences().gui_show_browser_icons=browser_icons->getCheck(); mainwindow->getTrackView()->updateIcons(); } if (!(selected==current)) { GMIconTheme::instance()->load(); redraw(); } mainwindow->configureStatusbar(statusbarbutton->getCheck()); mainwindow->configureToolbar((toolbar_docktop->getCurrentItem()==0),toolbar_showlabels->getCheck(),toolbar_bigicons->getCheck()); if (GMPlayerManager::instance()->getPreferences().gui_show_playing_albumcover) { if (GMPlayerManager::instance()->playing()) GMPlayerManager::instance()->update_track_display(false); } else { mainwindow->loadCover(FXString::null); } GMPlayerManager::instance()->update_tray_icon(); // Key Words may have changed. mainwindow->getTrackView()->resort(); mainwindow->getSourceView()->resort(); return 1; } void GMPreferencesDialog::initColorThemes() { for(FXuint i=0;iappendItem(ColorThemes[i].name,NULL,(void*)&ColorThemes[i]); } theme=-1; for(FXuint i=0;iprependItem(tr("Current"),NULL,(void*)¤t); theme=0; } } void GMPreferencesDialog::updateColorThemes() { theme=-1; for (FXint i=0;igetNumItems();i++){ if (selected==*(ColorTheme*)colorpresets->getItemData(i)){ theme=i; return; } } if (theme==-1) { theme=colorpresets->getNumItems(); colorpresets->appendItem(tr("Custom"),NULL,(void*)&selected); } else if (themegetNumItems()-1) { if (colorpresets->getItemData(colorpresets->getNumItems()-1)==&selected) colorpresets->removeItem(colorpresets->getNumItems()-1); } } long GMPreferencesDialog::onCmdIconTheme(FXObject*,FXSelector,void*){ GMIconTheme::instance()->setCurrentTheme((FXint)(FXival)themelist->getItemData(themelist->getCurrentItem())); GMIconTheme::instance()->load(); redraw(); return 1; } long GMPreferencesDialog::onCmdLastFMScrobble(FXObject*,FXSelector,void*){ if (lastfm_scrobble->getCheck()) GMPlayerManager::instance()->getAudioScrobbler()->enable(); else GMPlayerManager::instance()->getAudioScrobbler()->disable(); return 1; } long GMPreferencesDialog::onCmdLastFMService(FXObject*,FXSelector,void*){ if (lastfm_service->getCurrentItem()!=SERVICE_CUSTOM) { GMPlayerManager::instance()->getAudioScrobbler()->service(lastfm_service->getCurrentItem()); lastfm_username->setText(FXString::null,false); lastfm_password->setText(FXString::null,false); password_set=false; if (lastfm_service->getNumItems()==3) { lastfm_service->removeItem(2); lastfm_service->setNumVisible(2); } lastfm_join->show(); } if (lastfm_service->getCurrentItem()==SERVICE_LASTFM){ lastfm_username->hide(); lastfm_username_label->hide(); lastfm_password->hide(); lastfm_password_label->hide(); } else { lastfm_username->show(); lastfm_username_label->show(); lastfm_password->show(); lastfm_password_label->show(); } return 1; } long GMPreferencesDialog::onCmdLastFMPassWord(FXObject*,FXSelector,void*){ // fxmessage("onCmdLastFMPassWord %d\n",password_set); if (!GMPlayerManager::instance()->getAudioScrobbler()->isBanned() && password_set) { lastfm_scrobble->setCheck(true); GMPlayerManager::instance()->getAudioScrobbler()->login(lastfm_username->getText(),lastfm_password->getText()); } return 1; } long GMPreferencesDialog::onFocusLastFMPassWord(FXObject*,FXSelector,void*){ // fxmessage("onFocusLastFMPassWord %d\n",password_set); if (password_set==false) { password_set=true; lastfm_password->setText(FXString::null,false); } return 0; } long GMPreferencesDialog::onCmdLastFMUserName(FXObject*,FXSelector sel,void*){ // if (GMPlayerManager::instance()->getAudioScrobbler()->getUsername()!=lastfm_username->getText()){ lastfm_password->setText(FXString::null,false); password_set=true; if (FXSELTYPE(sel)==SEL_COMMAND) lastfm_password->setFocus(); // } return 1; } long GMPreferencesDialog::onCmdLastFMJoin(FXObject*,FXSelector,void*){ FXuint service = GMPlayerManager::instance()->getAudioScrobbler()->getService(); if (service==SERVICE_LASTFM) { if (!gm_open_browser("https://www.last.fm/join/")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit https://www.last.fm/join/"); } } else if (service==SERVICE_LIBREFM) { if (!gm_open_browser("http://alpha.libre.fm/register.php")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit http://alpha.libre.fm/register.php"); } } return 1; } long GMPreferencesDialog::onCmdElementColor(FXObject*,FXSelector sel,void* rgba) { FXColor color = (FXColor)(FXuval)rgba; switch(FXSELID(sel)){ case ID_BASE_COLOR : selected.base = color; selected.shadow = makeShadowColor(selected.base); selected.hilite = makeHiliteColor(selected.base); break; case ID_BORDER_COLOR : selected.border = color; break; case ID_BACK_COLOR : selected.back = color; break; case ID_FORE_COLOR : selected.fore = color; break; case ID_SHADOW_COLOR : selected.shadow=color; break; case ID_HILITE_COLOR : selected.hilite=color; break; case ID_SEL_BACK_COLOR: selected.selback=color; break; case ID_SEL_FORE_COLOR: selected.selfore=color; break; case ID_MENU_BACK_COLOR: selected.menuback=color; break; case ID_MENU_FORE_COLOR: selected.menufore=color; break; case ID_TIP_BACK_COLOR: selected.tipback=color; break; case ID_TIP_FORE_COLOR: selected.tipfore=color; break; case ID_PLAY_BACK_COLOR: selected.playback=color; break; case ID_PLAY_FORE_COLOR: selected.playfore=color; break; case ID_TRAY_COLOR: selected.trayback=color; break; case ID_ALTERNATIVE_BACK_COLOR: selected.altback=color; break; } updateColors(); updateColorThemes(); return 1; } long GMPreferencesDialog::onUpdElementColor(FXObject*sender,FXSelector sel,void*) { FXuval rgba = 0; switch(FXSELID(sel)){ case ID_BASE_COLOR : rgba=selected.base; break; case ID_BORDER_COLOR : rgba=selected.border; break; case ID_BACK_COLOR : rgba=selected.back; break; case ID_FORE_COLOR : rgba=selected.fore; break; case ID_SHADOW_COLOR : rgba=selected.shadow; break; case ID_HILITE_COLOR : rgba=selected.hilite; break; case ID_SEL_BACK_COLOR: rgba=selected.selback; break; case ID_SEL_FORE_COLOR: rgba=selected.selfore; break; case ID_MENU_BACK_COLOR: rgba=selected.menuback; break; case ID_MENU_FORE_COLOR: rgba=selected.menufore; break; case ID_TIP_BACK_COLOR: rgba=selected.tipback; break; case ID_TIP_FORE_COLOR: rgba=selected.tipfore; break; case ID_PLAY_BACK_COLOR: rgba=selected.playback; break; case ID_PLAY_FORE_COLOR: rgba=selected.playfore; break; case ID_TRAY_COLOR: rgba=selected.trayback; break; case ID_ALTERNATIVE_BACK_COLOR: rgba=selected.altback; break; } sender->tryHandle(this,FXSEL(SEL_COMMAND,FXColorWell::ID_SETINTVALUE),&rgba); return 1; } long GMPreferencesDialog::onCmdColorTheme(FXObject*,FXSelector,void*ptr) { theme=(FXint)(FXival)ptr; ColorTheme *theme_selected=reinterpret_cast(colorpresets->getItemData(theme)); selected.base = theme_selected->base; selected.border = theme_selected->border; selected.back = theme_selected->back; selected.altback = theme_selected->altback; selected.fore = theme_selected->fore; selected.selfore = theme_selected->selfore; selected.selback = theme_selected->selback; selected.tipfore = theme_selected->tipfore; selected.tipback = theme_selected->tipback; selected.menufore= theme_selected->menufore; selected.menuback= theme_selected->menuback; selected.shadow = makeShadowColor(selected.base); selected.hilite = makeHiliteColor(selected.base); selected.playback = theme_selected->playback; selected.playfore = theme_selected->playfore; selected.trayback = theme_selected->base; updateColors(); return 1; } long GMPreferencesDialog::onUpdColorTheme(FXObject*sender,FXSelector,void*) { sender->tryHandle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETINTVALUE),&theme); return 1; } void GMPreferencesDialog::updateColors(){ register FXWindow *w=FXApp::instance()->getRootWindow(); FX7Segment * sevensegment; FXTextField * gmtextfield; FXIconList * iconlist; FXList * list; FXListBox * listbox; FXTreeList * treelist; FXComboBox * combobox; FXButton * button; FXFrame * frame; FXLabel * label; FXPopup * popup; FXMenuTitle * menutitle; FXMenuCheck * menucheck; FXMenuRadio * menuradio; FXMenuCaption * menucaption; FXMenuSeparator * menuseparator; FXText * text; FXFoldingList * foldinglist; FXMDIChild * mdichild; FXTable * table; FXDockTitle * docktitle; FXPacker * packer; FXHeader * header; FXGroupBox * groupbox; FXScrollBar * scrollbar; FXSlider * slider; FXStatusLine * statusline; FXDragCorner * dragcorner; GMTreeList * gmtreelist; GMTrackList * gmtracklist; FXRadioButton * radiobutton; GMCheckButton * checkbutton; FXToolTip * tooltip; GMList * gmlist; GMListBox * gmlistbox; GMComboBox * gmcombobox; GMScrollFrame * gmscrollframe; GMTabFrame * gmtabframe; GMImageFrame * gmimageframe; GMCoverFrame * gmcoverframe; GMImageView * gmimageview; GMMenuPane * gmmenupane; GMProgressBar * gmprogressbar; // GMTrackProgressBar * gmtrackprogressbar; GMSpinner * gmspinner; while(w){ w->setBackColor(selected.base); if ((frame=dynamic_cast(w))) { frame->setBaseColor(selected.base); frame->setBackColor(selected.base); frame->setShadowColor(selected.shadow); frame->setHiliteColor(selected.hilite); frame->setBorderColor(selected.border); if ((label=dynamic_cast(w))) { label->setTextColor(selected.fore); if ((button=dynamic_cast(w))) { if (dynamic_cast(button->getParent())){ w->setBackColor(selected.back); } else { w->setBackColor(selected.base); } } else if ((checkbutton=dynamic_cast(w))) { checkbutton->setCheckColor(selected.fore); checkbutton->setBoxColor(selected.back); } else if ((radiobutton=dynamic_cast(w))) { radiobutton->setRadioColor(selected.fore); radiobutton->setDiskColor(selected.back); } } else if ((gmtextfield=dynamic_cast(w))) { w->setBackColor(selected.back); gmtextfield->setTextColor(selected.fore); gmtextfield->setSelTextColor(selected.selfore); gmtextfield->setSelBackColor(selected.selback); gmtextfield->setBorderColor(selected.shadow); } else if ((docktitle=dynamic_cast(w))) { docktitle->setCaptionColor(selected.selfore); docktitle->setBackColor(selected.selback); } else if ((header=dynamic_cast(w))) { header->setTextColor(selected.fore); } else if ((statusline=dynamic_cast(w))) { statusline->setTextColor(selected.fore); } else if ((sevensegment=dynamic_cast(w))) { sevensegment->setTextColor(selected.fore); } else if ((slider=dynamic_cast(w))) { slider->setSlotColor(selected.back); } else if ((gmimageframe=dynamic_cast(w))) { gmimageframe->setBorderColor(selected.shadow); gmimageframe->setBackColor(selected.back); /// fixme, only for coverframe in mainwindow } else if ((gmprogressbar=dynamic_cast(w))) { gmprogressbar->setBorderColor(selected.shadow); gmprogressbar->setBarColor(selected.selback); gmprogressbar->setTextAltColor(selected.selfore); } /* else if ((gmtrackprogressbar=dynamic_cast(w))) { gmtrackprogressbar->setBorderColor(selected.shadow); gmtrackprogressbar->setBarColor(selected.selback); gmtrackprogressbar->setTextAltColor(selected.selfore); } */ } else if ((packer=dynamic_cast(w))) { packer->setBaseColor(selected.base); packer->setBackColor(selected.base); packer->setShadowColor(selected.shadow); packer->setHiliteColor(selected.hilite); packer->setBorderColor(selected.border); if ((gmscrollframe=dynamic_cast(w))){ gmscrollframe->setBorderColor(selected.shadow); } else if ((gmtabframe=dynamic_cast(w))){ gmtabframe->setBorderColor(selected.shadow); } else if ((gmcoverframe=dynamic_cast(w))){ gmcoverframe->setBorderColor(selected.shadow); gmcoverframe->setBackColor(selected.back); } else if ((combobox=dynamic_cast(w))) { w->setBackColor(selected.back); } else if ((listbox=dynamic_cast(w))) { //w->setBackColor(selected.back); if ((gmlistbox=dynamic_cast(w))) { gmlistbox->setBorderColor(selected.shadow); } } else if ((groupbox=dynamic_cast(w))) { groupbox->setTextColor(selected.fore); } else if ((gmspinner=dynamic_cast(w))) { gmspinner->setBorderColor(selected.shadow); gmspinner->setUpArrowColor(selected.fore); gmspinner->setDownArrowColor(selected.fore); } } else if ((popup=dynamic_cast(w))){ popup->setBaseColor(selected.base); popup->setShadowColor(selected.shadow); popup->setHiliteColor(selected.hilite); popup->setBorderColor(selected.border); if ((gmmenupane=dynamic_cast(w)) || (gmlistbox=dynamic_cast(w->getParent())) || (gmcombobox=dynamic_cast(w->getParent()))){ popup->setBorderColor(selected.shadow); } } else if ((menucaption=dynamic_cast(w))) { w->setBackColor(selected.back); menucaption->setTextColor(selected.fore); menucaption->setSelTextColor(selected.menufore); menucaption->setSelBackColor(selected.menuback); menucaption->setShadowColor(makeShadowColor(selected.back)); menucaption->setHiliteColor(makeHiliteColor(selected.back)); if ((menucheck=dynamic_cast(w))) { menucheck->setBoxColor(selected.back); } else if ((menuradio=dynamic_cast(w))) { menuradio->setRadioColor(selected.back); } else if ((menutitle=dynamic_cast(w))) { w->setBackColor(selected.base); menutitle->setTextColor(selected.fore); menutitle->setSelTextColor(selected.menufore); menutitle->setSelBackColor(selected.menuback); menutitle->setShadowColor(selected.shadow); menutitle->setHiliteColor(selected.hilite); } } else if ((menuseparator=dynamic_cast(w))) { menuseparator->setShadowColor(makeShadowColor(selected.back)); menuseparator->setHiliteColor(makeHiliteColor(selected.back)); } else if ((scrollbar=dynamic_cast(w))) { scrollbar->setShadowColor(selected.shadow); scrollbar->setHiliteColor(selected.hilite); scrollbar->setBorderColor(selected.border); scrollbar->setArrowColor(selected.fore); } else if ((dragcorner=dynamic_cast(w))) { dragcorner->setShadowColor(selected.shadow); dragcorner->setHiliteColor(selected.hilite); } else if (dynamic_cast(w)) { if ((text=dynamic_cast(w))) { w->setBackColor(selected.back); text->setTextColor(selected.fore); text->setSelTextColor(selected.selfore); text->setSelBackColor(selected.selback); } else if ((list=dynamic_cast(w))) { w->setBackColor(selected.back); list->setTextColor(selected.fore); list->setSelTextColor(selected.selfore); list->setSelBackColor(selected.selback); if ((gmlist=dynamic_cast(w))) { gmlist->setRowColor(selected.altback); ((FXFrame*)gmlist->getParent())->setBorderColor(selected.shadow); } } else if ((treelist=dynamic_cast(w))) { w->setBackColor(selected.back); treelist->setTextColor(selected.fore); treelist->setLineColor(selected.shadow); treelist->setSelTextColor(selected.selfore); treelist->setSelBackColor(selected.selback); if ((gmtreelist=dynamic_cast(w))) { gmtreelist->setRowColor(selected.altback); ((FXFrame*)gmtreelist->getParent())->setBorderColor(selected.shadow); } else { treelist->setSelTextColor(selected.selfore); treelist->setSelBackColor(selected.selback); } } else if ((iconlist=dynamic_cast(w))) { w->setBackColor(selected.back); iconlist->setTextColor(selected.fore); iconlist->setSelTextColor(selected.selfore); iconlist->setSelBackColor(selected.selback); } else if ((gmtracklist=dynamic_cast(w))) { w->setBackColor(selected.back); //((FXFrame*)gmtracklist->getParent())->setBorderColor(selected.shadow); gmtracklist->setTextColor(selected.fore); gmtracklist->setSelTextColor(selected.selfore); gmtracklist->setSelBackColor(selected.selback); gmtracklist->setRowColor(selected.altback); gmtracklist->setActiveTextColor(selected.playfore); gmtracklist->setActiveColor(selected.playback); } else if ((foldinglist=dynamic_cast(w))) { w->setBackColor(selected.back); foldinglist->setTextColor(selected.fore); foldinglist->setSelTextColor(selected.selfore); foldinglist->setSelBackColor(selected.selback); foldinglist->setLineColor(selected.shadow); } else if ((table=dynamic_cast(w))) { w->setBackColor(selected.back); table->setTextColor(selected.fore); table->setSelTextColor(selected.selfore); table->setSelBackColor(selected.selback); } } else if ((mdichild=dynamic_cast(w))) { mdichild->setBackColor(selected.base); mdichild->setBaseColor(selected.base); mdichild->setShadowColor(selected.shadow); mdichild->setHiliteColor(selected.hilite); mdichild->setBorderColor(selected.border); mdichild->setTitleColor(selected.selfore); mdichild->setTitleBackColor(selected.selback); } else if ((tooltip=dynamic_cast(w))){ tooltip->setTextColor(selected.tipfore); tooltip->setBackColor(selected.tipback); } else if ((gmimageview=dynamic_cast(w))){ gmimageview->setBackColor(selected.back); } w->update(); if(w->getFirst()){ w=w->getFirst(); continue; } while(!w->getNext() && w->getParent()){ w=w->getParent(); } w=w->getNext(); } selected.save(); if (GMPlayerManager::instance()->getTrayIcon()) GMPlayerManager::instance()->getTrayIcon()->updateIcon(); } long GMPreferencesDialog::onCmdChangeFont(FXObject*,FXSelector,void*){ GMFontDialog dialog(this,tr("Select Normal Font")); FXFont * font = FXApp::instance()->getNormalFont(); FXFontDesc fontdescription; #if FOXVERSION < FXVERSION(1,7,17) font->getFontDesc(fontdescription); fontdescription.size = font->getActualSize(); fontdescription.weight = font->getActualWeight(); fontdescription.setwidth = font->getActualSetWidth(); fontdescription.slant = font->getActualSlant(); #else fontdescription = font->getActualFontDesc(); #endif strncpy(fontdescription.face,font->getActualName().text(),sizeof(fontdescription.face)); dialog.setFontDesc(fontdescription); if(dialog.execute(PLACEMENT_SCREEN)){ fontdescription=dialog.getFontDesc(); GMApp::instance()->setFont(fontdescription); updateFonts(); } return 1; } void GMPreferencesDialog::updateFonts() { GMPlayerManager::instance()->getMainWindow()->layoutToolBarButtons(); GMPlayerManager::instance()->getMainWindow()->getTrackView()->updateFont(); redraw(); FXint nw =getDefaultWidth(); FXint nh = getDefaultHeight(); resize(nw,nh); } static void fancyfontname(FXFont * font,FXString & name) { name = font->getActualName().before('[').trimEnd(); const FXchar *wgt=NULL,*slt=NULL,*wid=NULL; const FXint size=font->getActualSize()/10; switch(font->getActualSetWidth()){ case FXFont::UltraCondensed: wid="Ultra Condensed"; break; case FXFont::ExtraCondensed: wid="Extra Condensed"; break; case FXFont::Condensed: wid="Condensed"; break; case FXFont::SemiCondensed: wid="Semi Condensed"; break; case FXFont::NonExpanded: wid=NULL; break; case FXFont::SemiExpanded: wid="Semi Expanded"; break; case FXFont::Expanded: wid="Expanded"; break; case FXFont::ExtraExpanded: wid="Extra Expanded"; break; case FXFont::UltraExpanded: wid="Ultra Expanded"; break; default: wid=NULL; break; } switch(font->getActualWeight()){ case FXFont::Thin : wgt=fxtr("Thin"); break; case FXFont::ExtraLight: wgt=fxtr("Extra Light"); break; case FXFont::Light : wgt=fxtr("Light"); break; case FXFont::Normal : wgt=NULL; break; case FXFont::Medium : wgt=fxtr("Medium"); break; case FXFont::DemiBold : wgt=fxtr("Demibold"); break; case FXFont::Bold : wgt=fxtr("Bold"); break; case FXFont::ExtraBold : wgt=fxtr("Extra Bold"); break; case FXFont::Black : wgt=fxtr("Heavy"); break; default: wgt=NULL; break; } switch(font->getActualSlant()){ case FXFont::ReverseOblique: slt="Reverse Oblique"; break; case FXFont::ReverseItalic: slt="Reverse Italic"; break; case FXFont::Straight: slt=NULL; break; case FXFont::Italic: slt="Italic"; break; case FXFont::Oblique: slt="Oblique"; break; default: slt=NULL; break; } if (wgt && slt && wid) name+=GMStringFormat(", %s %s %s, %d",wgt,wid,slt,size); else if (wgt && slt) name+=GMStringFormat(", %s %s, %d",wgt,slt,size); else if (wgt && wid) name+=GMStringFormat(", %s %s, %d",wgt,wid,size); else if (wid && slt) name+=GMStringFormat(", %s %s, %d",wid,slt,size); else if (slt) name+=GMStringFormat(", %s, %d",slt,size); else if (wgt) name+=GMStringFormat(", %s, %d",wgt,size); else if (wid) name+=GMStringFormat(", %s, %d",wid,size); else name+=GMStringFormat(", %d",size); } long GMPreferencesDialog::onUpdFont(FXObject*sender,FXSelector,void*){ FXString fontname; FXFont * font = FXApp::instance()->getNormalFont(); fancyfontname(font,fontname); sender->tryHandle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETSTRINGVALUE),&fontname); return 1; } gogglesmm-0.12.7/src/GMTaskManager.h0000644000175000001440000000512011714631566015676 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTHREAD_H #define GMTHREAD_H class GMTaskManager; class GMTask { friend class GMTaskManager; private: GMTask(const GMTask&); GMTask &operator=(const GMTask&); protected: GMTaskManager * taskmanager; FXMessageChannel * mc; volatile FXbool processing; protected: FXObject * target; FXSelector message; public: GMTask(FXObject*tgt=NULL,FXSelector sel=0); void setTarget(FXObject * tgt) { target=tgt; } void setSelector(FXSelector sel) { message=sel; } virtual FXint run() = 0; virtual ~GMTask(); }; typedef FXArray GMTaskList; class GMTaskManager : public FXThread { protected: FXMutex mutex; FXCondition condition_task; volatile FXbool processing; FXbool started; protected: FXbool wait(); FXbool next(); protected: GMTask * active; FXObject* target; FXSelector message; FXMessageChannel mc; GMTaskList tasks; protected: FXint run(); public: GMTaskManager(FXObject*tgt=NULL,FXSelector sel=0); void run(GMTask*); void shutdown(); void cancelTask(); void setStatus(const FXString &); virtual ~GMTaskManager(); }; #endif gogglesmm-0.12.7/src/GMColumnDialog.cpp0000644000175000001440000002331711525430601016404 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMList.h" #include "GMTrackList.h" #include "GMColumnDialog.h" #define ICON_SPACING 4 // Spacing between icon and label #define SIDE_SPACING 6 // Left or right spacing between items #define LINE_SPACING 4 // Line spacing between items class FXCheckListItem : public GMListItem { FXDECLARE(FXCheckListItem) friend class FXList; protected: FXCheckListItem(){} //#if FOXVERSION < FXVERSION(1,7,0) // virtual void draw(const GMList* list,FXDC& dc,FXint x,FXint y,FXint w,FXint h); //#else virtual void draw(const GMList* list,FXDC& dc,FXint x,FXint y,FXint w,FXint h) const; //#endif virtual FXint hitItem(const FXList* list,FXint x,FXint y) const; public: enum { CHECKED = 32 }; public: /// Construct new item with given text, icon, and user-data FXCheckListItem(const FXString& text,FXbool check=true,void* ptr=NULL):GMListItem(text,NULL,ptr) {if (check) state|=CHECKED; } /// Return width of item as drawn in list virtual FXint getWidth(const FXList* list) const; /// Return height of item as drawn in list virtual FXint getHeight(const FXList* list) const; FXbool checked() const { return (state&CHECKED); } void toggle() { if (state&CHECKED) state&=~CHECKED; else state|=CHECKED; } }; FXIMPLEMENT(FXCheckListItem,FXListItem,NULL,0); void FXCheckListItem::draw(const GMList* list,FXDC& dc,FXint xx,FXint yy,FXint ww,FXint hh) const { //#endif register FXFont *font=list->getFont(); register FXint ih=0,th=0; if(icon) ih=icon->getHeight(); if(!label.empty()) th=font->getFontHeight(); if(isSelected()) dc.setForeground(list->getSelBackColor()); else dc.setForeground(list->getBackColor()); // FIXME maybe paint background in onPaint? dc.fillRectangle(xx,yy,ww,hh); if(hasFocus()){ dc.drawFocusRectangle(xx+1,yy+1,ww-2,hh-2); } xx+=SIDE_SPACING/2; FXint yyy=yy+(hh-10)/2; if(!isEnabled()) dc.setForeground(makeShadowColor(list->getBackColor())); else dc.setForeground(list->getBackColor()); dc.fillRectangle(xx+1,yyy+1,9,9); dc.setForeground(list->getApp()->getBorderColor()); // dc.setForeground(shadowColor); dc.drawRectangle(xx,yyy,10,10); // dc.drawRectangle(xx,yyy,9,9); dc.setForeground(list->getTextColor()); // Draw the check if(state&CHECKED){ FXSegment seg[6]; seg[0].x1=2+xx; seg[0].y1=4+yyy; seg[0].x2=4+xx; seg[0].y2=6+yyy; seg[1].x1=2+xx; seg[1].y1=5+yyy; seg[1].x2=4+xx; seg[1].y2=7+yyy; seg[2].x1=2+xx; seg[2].y1=6+yyy; seg[2].x2=4+xx; seg[2].y2=8+yyy; seg[3].x1=4+xx; seg[3].y1=6+yyy; seg[3].x2=8+xx; seg[3].y2=2+yyy; seg[4].x1=4+xx; seg[4].y1=7+yyy; seg[4].x2=8+xx; seg[4].y2=3+yyy; seg[5].x1=4+xx; seg[5].y1=8+yyy; seg[5].x2=8+xx; seg[5].y2=4+yyy; dc.drawLineSegments(seg,6); } xx+=ICON_SPACING+9; if(icon){ dc.drawIcon(icon,xx,yy+(hh-ih)/2); xx+=ICON_SPACING+icon->getWidth(); } if(!label.empty()){ dc.setFont(font); if(!isEnabled()) dc.setForeground(makeShadowColor(list->getBackColor())); else if(isSelected()) dc.setForeground(list->getSelTextColor()); else dc.setForeground(list->getTextColor()); dc.drawText(xx,yy+(hh-th)/2+font->getFontAscent(),label); } } // See if item got hit, and where: 0 is outside, 1 is icon, 2 is text FXint FXCheckListItem::hitItem(const FXList* list,FXint xx,FXint yy) const { register FXFont *font=list->getFont(); register FXint iw=0,ih=0,tw=0,th=0,cx,ix,iy,tx,ty,h; if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); } if(!label.empty()){ tw=4+font->getTextWidth(label.text(),label.length()); th=4+font->getFontHeight(); } h=LINE_SPACING+FXMAX3(th,ih,9); cx=SIDE_SPACING/2; ix=cx+9+ICON_SPACING; tx=cx+9+ICON_SPACING; if(iw) tx+=iw+ICON_SPACING; iy=(h-ih)/2; ty=(h-th)/2; if (cx<=xx && xxgetFont(); register FXint w=9; if(icon){ w=icon->getWidth()+ICON_SPACING; } if(!label.empty()){ if(w) w+=ICON_SPACING; w+=font->getTextWidth(label.text(),label.length()); } return SIDE_SPACING+w; } // Get height of item FXint FXCheckListItem::getHeight(const FXList* list) const { register FXFont *font=list->getFont(); register FXint th=0,ih=0; if(icon){ ih=icon->getHeight(); } if(!label.empty()){ th=font->getFontHeight(); } return LINE_SPACING+FXMAX3(th,ih,9); } FXDEFMAP(GMColumnDialog) GMColumnDialogMap[]={ FXMAPFUNC(SEL_UPDATE,GMColumnDialog::ID_MOVE_UP,GMColumnDialog::onUpdMoveUp), FXMAPFUNC(SEL_UPDATE,GMColumnDialog::ID_MOVE_DOWN,GMColumnDialog::onUpdMoveDown), FXMAPFUNC(SEL_COMMAND,GMColumnDialog::ID_MOVE_UP,GMColumnDialog::onCmdMoveUp), FXMAPFUNC(SEL_COMMAND,GMColumnDialog::ID_MOVE_DOWN,GMColumnDialog::onCmdMoveDown), FXMAPFUNC(SEL_LEFTBUTTONPRESS,GMColumnDialog::ID_LIST,GMColumnDialog::onListLeftBtnPress), }; FXIMPLEMENT(GMColumnDialog,FXDialogBox,GMColumnDialogMap,ARRAYNUMBER(GMColumnDialogMap)); GMColumnDialog::GMColumnDialog(){ } GMColumnDialog::GMColumnDialog(FXWindow *window,GMColumnList & cols) : FXDialogBox(window,FXString::null,DECOR_ALL,0,0,0,0,3,3,3,3) { setTitle(tr("Configure Columns")); FXHorizontalFrame * buttonframe = new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,0,0,0,0,0,0,0,0); new GMButton(buttonframe,tr("&Accept"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); new GMButton(buttonframe,tr("&Cancel"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); new FXSeparator(this,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); new FXLabel(this,tr("Choose the order of information to appear\nin the track list."),NULL,LAYOUT_SIDE_TOP|JUSTIFY_LEFT); FXHorizontalFrame * main = new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0); FXVerticalFrame * control = new FXVerticalFrame(main,LAYOUT_FILL_Y|LAYOUT_RIGHT|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0); new GMButton(control,tr("Move Up"),NULL,this,ID_MOVE_UP); new GMButton(control,tr("Move Down"),NULL,this,ID_MOVE_DOWN); GMScrollFrame * sunken = new GMScrollFrame(main); list = new GMList(sunken,this,ID_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LIST_BROWSESELECT); FXbool insert=false; for (FXint i=0;igetNumItems();j++) { if (cols[i].index < ((GMColumn*)list->getItemData(j))->index) { list->insertItem(j,new FXCheckListItem(cols[i].name,cols[i].show,&cols[i])); insert=true; break; } } if (!insert) list->appendItem(new FXCheckListItem(cols[i].name,cols[i].show,&cols[i])); } list->setNumVisible(10); } void GMColumnDialog::saveIndex() { for (FXint i=0;igetNumItems();i++){ GMColumn * c = (GMColumn*)list->getItemData(i); c->index = i; c->show = ((FXCheckListItem*)list->getItem(i))->checked(); } } long GMColumnDialog::onListLeftBtnPress(FXObject*,FXSelector,void*ptr){ FXEvent* event=(FXEvent*)ptr; FXint index,code; index=list->getItemAt(event->win_x,event->win_y); if (index>=0) { code=list->hitItem(index,event->win_x,event->win_y); if (code==3) { ((FXCheckListItem*)list->getItem(index))->toggle(); list->updateItem(index); } } return 0; } long GMColumnDialog::onCmdMoveUp(FXObject*,FXSelector,void*){ list->moveItem(list->getCurrentItem()-1,list->getCurrentItem()); return 1; } long GMColumnDialog::onUpdMoveUp(FXObject*sender,FXSelector,void*){ if (list->getCurrentItem()>0) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMColumnDialog::onCmdMoveDown(FXObject*,FXSelector,void*){ list->moveItem(list->getCurrentItem()+1,list->getCurrentItem()); return 1; } long GMColumnDialog::onUpdMoveDown(FXObject*sender,FXSelector,void*){ if (list->getCurrentItem()getNumItems()-1) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } gogglesmm-0.12.7/src/GMTrackItem.cpp0000644000175000001440000005154211525430601015713 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include "gmdefs.h" #include "GMTrackList.h" #include "GMTrackItem.h" #include "GMList.h" #include "GMSource.h" #include "GMTrackView.h" #include "GMPlayerManager.h" #define SIDE_SPACING 4 // Left or right spacing between items #define DETAIL_TEXT_SPACING 2 // Spacing between text and icon in detail icon mode #define MINI_TEXT_SPACING 2 // Spacing between text and icon in mini icon mode #define BIG_LINE_SPACING 6 // Line spacing in big icon mode #define BIG_TEXT_SPACING 2 // Spacing between text and icon in big icon mode #define ITEM_SPACE 128 // Default space for item FXint GMDBTrackItem::max_time=0; FXint GMDBTrackItem::max_trackno=0; FXint GMDBTrackItem::max_queue=0; FXint GMDBTrackItem::max_digits(FXint num){ if (num>9) { FXint n=0; while(num>0) { ++n; num/=10; } return n; } return 1; } GMDBTrackItem::GMDBTrackItem(FXint track_id,const FXchar * track_title,const FXchar * track_artist,const FXchar * track_album_artist,const FXchar * track_album,const FXchar * track_genre,FXint track_time,FXuint track_no,FXint track_queue,FXushort track_year,FXushort track_album_year) : GMTrackItem(), title(track_title), artist(track_artist), album_artist(track_album_artist), album(track_album),genre(track_genre), time(track_time), no(track_no), queue(track_queue), year(track_year), album_year(track_album_year) { id=track_id; state|=GMTrackItem::DRAGGABLE; } GMDBTrackItem::~GMDBTrackItem(){ } const FXString * GMDBTrackItem::getColumnData(FXint type,FXString &text,FXuint & justify,FXint & max) const{ const FXString * textptr; justify=COLUMN_JUSTIFY_NORMAL; switch(type){ case HEADER_QUEUE : text.format("%d",queue); textptr=&text; justify=COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED; max=GMDBTrackItem::max_queue; break; case HEADER_TRACK : if (GMTRACKNO((FXuint)(FXuval)no)>0) { text.format("%d",GMTRACKNO((FXuint)(FXuval)no)); textptr=&text; justify=COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED; max=GMDBTrackItem::max_trackno; } else { textptr=NULL; } break; case HEADER_DISC : if (GMDISCNO((FXuint)(FXuval)no)>0) { text.format("%d",GMDISCNO((FXuint)(FXuval)no)); textptr=&text; } else { textptr=NULL; } break; case HEADER_TITLE : textptr = &title; break; case HEADER_ALBUM : textptr = &album; break; case HEADER_ARTIST : textptr = &artist; break; case HEADER_ALBUM_ARTIST : textptr = &album_artist; break; case HEADER_GENRE : textptr = &genre; break; case HEADER_YEAR : //justify=COLUMN_JUSTIFY_CENTER_RIGHT_ALIGNED; //max=9999; if (year>0) {text.format("%d",year); textptr=&text; } else textptr=NULL; break; case HEADER_TIME : /*textptr = ×tring;*/ text.format("%d:%.2d",time/60,time%60); textptr=&text; justify=COLUMN_JUSTIFY_CENTER_RIGHT_ALIGNED; max=GMDBTrackItem::max_time; break; default : textptr=NULL; break; } return textptr; } static inline FXbool begins_with_keyword(const FXString & t){ for (FXint i=0;igetPreferences().gui_sort_keywords.no();i++){ if (comparecase(t,GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i],GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i].length())==0) return TRUE; } return FALSE; } FXint GMDBTrackItem::browseSort(const GMTrackItem * pa,const GMTrackItem * pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (GMTrackView::album_by_year) { if (ta->album_year > tb->album_year) return (GMTrackView::reverse_album) ? -1 : 1; else if (ta->album_year < tb->album_year) return (GMTrackView::reverse_album) ? 1 : -1; } if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return (GMTrackView::reverse_album) ? -x : x; a=b=0; if (begins_with_keyword(ta->album_artist)) a=FXMIN(ta->album_artist.length()-1,ta->album_artist.find(' ')+1); if (begins_with_keyword(tb->album_artist)) b=FXMIN(tb->album_artist.length()-1,tb->album_artist.find(' ')+1); x = comparecase(&ta->album_artist[a],&tb->album_artist[b]); if (x!=0) return (GMTrackView::reverse_artist) ? -x : x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::ascendingTitle(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0; if (begins_with_keyword(ta->title)) a=FXMIN(ta->title.length()-1,ta->title.find(' ')+1); if (begins_with_keyword(tb->title)) b=FXMIN(tb->title.length()-1,tb->title.find(' ')+1); return comparecase(&ta->title[a],&tb->title[b]); } FXint GMDBTrackItem::descendingTitle(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0; if (begins_with_keyword(ta->title)) a=FXMIN(ta->title.length()-1,ta->title.find(' ')+1); if (begins_with_keyword(tb->title)) b=FXMIN(tb->title.length()-1,tb->title.find(' ')+1); return -comparecase(&ta->title[a],&tb->title[b]); } FXint GMDBTrackItem::ascendingTrack(const GMTrackItem* pa,const GMTrackItem* pb){ register const FXuint a=GMTRACKNO((FXuint)(FXuval)((GMDBTrackItem*)pa)->no); register const FXuint b=GMTRACKNO((FXuint)(FXuval)((GMDBTrackItem*)pb)->no); if (a>b) return 1; else if (ano); register const FXint b=GMTRACKNO((FXuint)(FXuval)((GMDBTrackItem*)pb)->no); if (a>b) return -1; else if (ano); register const FXuint b=GMDISCNO((FXuint)(FXuval)((GMDBTrackItem*)pb)->no); if (a>b) return 1; else if (ano); register const FXint b=GMDISCNO((FXuint)(FXuval)((GMDBTrackItem*)pb)->no); if (a>b) return -1; else if (aqueue; register const FXint b=(FXint)(FXival)((GMDBTrackItem*)pb)->queue; if (a>b) return 1; else if (aqueue; register const FXint b=(FXint)(FXival)((GMDBTrackItem*)pb)->queue; if (a>b) return -1; else if (ayear; register const FXushort b=(FXushort)(FXival)((GMDBTrackItem*)pb)->year; if (a>b) return 1; if (ayear; register const FXushort b=(FXushort)(FXival)((GMDBTrackItem*)pb)->year; if (a>b) return -1; if (atime; register const FXint b=((GMDBTrackItem*)pb)->time; if (a>b) return 1; if (atime; register const FXint b=((GMDBTrackItem*)pb)->time; if (a>b) return -1; if (aalbum)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::descendingAlbum(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&tb->album[b],&ta->album[a]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::ascendingArtist(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (begins_with_keyword(ta->artist)) a=FXMIN(ta->artist.length()-1,ta->artist.find(' ')+1); if (begins_with_keyword(tb->artist)) b=FXMIN(tb->artist.length()-1,tb->artist.find(' ')+1); x = comparecase(&ta->artist[a],&tb->artist[b]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::descendingArtist(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (begins_with_keyword(ta->artist)) a=FXMIN(ta->artist.length()-1,ta->artist.find(' ')+1); if (begins_with_keyword(tb->artist)) b=FXMIN(tb->artist.length()-1,tb->artist.find(' ')+1); x = comparecase(&tb->artist[b],&ta->artist[a]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::ascendingAlbumArtist(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (begins_with_keyword(ta->album_artist)) a=FXMIN(ta->album_artist.length()-1,ta->album_artist.find(' ')+1); if (begins_with_keyword(tb->album_artist)) b=FXMIN(tb->album_artist.length()-1,tb->album_artist.find(' ')+1); x = comparecase(&ta->album_artist[a],&tb->album_artist[b]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::descendingAlbumArtist(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; if (begins_with_keyword(ta->album_artist)) a=FXMIN(ta->album_artist.length()-1,ta->album_artist.find(' ')+1); if (begins_with_keyword(tb->album_artist)) b=FXMIN(tb->album_artist.length()-1,tb->album_artist.find(' ')+1); x = comparecase(&tb->album_artist[b],&ta->album_artist[a]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::ascendingGenre(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; x = comparecase(ta->genre,tb->genre); if (x!=0) return x; if (begins_with_keyword(ta->artist)) a=FXMIN(ta->artist.length()-1,ta->artist.find(' ')+1); if (begins_with_keyword(tb->artist)) b=FXMIN(tb->artist.length()-1,tb->artist.find(' ')+1); x = comparecase(&ta->artist[a],&tb->artist[b]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMDBTrackItem::descendingGenre(const GMTrackItem* pa,const GMTrackItem* pb){ const GMDBTrackItem * const ta = (GMDBTrackItem*)pa; const GMDBTrackItem * const tb = (GMDBTrackItem*)pb; register FXint a=0,b=0,x; x = comparecase(tb->genre,ta->genre); if (x!=0) return x; if (begins_with_keyword(ta->artist)) a=FXMIN(ta->artist.length()-1,ta->artist.find(' ')+1); if (begins_with_keyword(tb->artist)) b=FXMIN(tb->artist.length()-1,tb->artist.find(' ')+1); x = comparecase(&ta->artist[a],&tb->artist[b]); if (x!=0) return x; a=b=0; if (begins_with_keyword(ta->album)) a=FXMIN(ta->album.length()-1,ta->album.find(' ')+1); if (begins_with_keyword(tb->album)) b=FXMIN(tb->album.length()-1,tb->album.find(' ')+1); x = comparecase(&ta->album[a],&tb->album[b]); if (x!=0) return x; /// Track & Disc if (ta->no>tb->no) return 1; else if (ta->nono) return -1; return 0; } FXint GMStreamTrackItem::max_trackno=0; FXint GMStreamTrackItem::max_digits(FXint num){ if (num>9) { FXint n=0; while(num>0) { ++n; num/=10; } return n; } return 1; } GMStreamTrackItem::GMStreamTrackItem(FXint track_id,const FXchar * track_title,const FXchar * track_genre,FXint track_no,FXint track_bitrate) : GMTrackItem(), title(track_title),genre(track_genre),bitrate(track_bitrate),no(track_no) { id=track_id; } const FXString * GMStreamTrackItem::getColumnData(FXint type,FXString &text,FXuint & justify,FXint & max) const{ const FXString * textptr; justify=COLUMN_JUSTIFY_NORMAL; switch(type){ case HEADER_TRACK : text.format("%d",GMTRACKNO((FXuint)(FXuval)no)); textptr=&text; justify=COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED; max=GMStreamTrackItem::max_trackno; break; case HEADER_TITLE : textptr = &title; break; case HEADER_GENRE : textptr = &genre; break; case HEADER_BITRATE : text.format("%d",bitrate); textptr=&text; break; default : textptr=NULL; break; } return textptr; } FXint GMStreamTrackItem::ascendingTime(const GMTrackItem* pa,const GMTrackItem* pb){ register const FXint a=(FXint)(FXival)((GMStreamTrackItem*)pa)->bitrate; register const FXint b=(FXint)(FXival)((GMStreamTrackItem*)pb)->bitrate; if (a>b) return 1; if (abitrate; register const FXint b=(FXint)(FXival)((GMStreamTrackItem*)pb)->bitrate; if (a>b) return -1; if (agenre,tb->genre); if (x!=0) return x; return ascendingTrack(pa,pb); } FXint GMStreamTrackItem::descendingGenre(const GMTrackItem* pa,const GMTrackItem* pb){ const GMStreamTrackItem * const ta = (GMStreamTrackItem*)pa; const GMStreamTrackItem * const tb = (GMStreamTrackItem*)pb; register FXint x; x = comparecase(tb->genre,ta->genre); if (x!=0) return x; return ascendingTrack(pa,pb); } FXint GMStreamTrackItem::ascendingTrack(const GMTrackItem* pa,const GMTrackItem* pb){ if (((GMStreamTrackItem*)pa)->no>((GMStreamTrackItem*)pb)->no) return 1; else if (((GMStreamTrackItem*)pa)->no<((GMStreamTrackItem*)pb)->no) return -1; return 0; } FXint GMStreamTrackItem::descendingTrack(const GMTrackItem* pa,const GMTrackItem* pb){ if (((GMStreamTrackItem*)pa)->no>((GMStreamTrackItem*)pb)->no) return -1; else if (((GMStreamTrackItem*)pa)->no<((GMStreamTrackItem*)pb)->no) return 1; return 0; } FXint GMStreamTrackItem::ascendingTitle(const GMTrackItem* pa,const GMTrackItem* pb){ const GMStreamTrackItem * const ta = (GMStreamTrackItem*)pa; const GMStreamTrackItem * const tb = (GMStreamTrackItem*)pb; register FXint a=0,b=0; if (begins_with_keyword(ta->title)) a=FXMIN(ta->title.length()-1,ta->title.find(' ')+1); if (begins_with_keyword(tb->title)) b=FXMIN(tb->title.length()-1,tb->title.find(' ')+1); return comparecase(&ta->title[a],&tb->title[b]); } FXint GMStreamTrackItem::descendingTitle(const GMTrackItem* pa,const GMTrackItem* pb){ const GMStreamTrackItem * const ta = (GMStreamTrackItem*)pa; const GMStreamTrackItem * const tb = (GMStreamTrackItem*)pb; register FXint a=0,b=0; if (begins_with_keyword(ta->title)) a=FXMIN(ta->title.length()-1,ta->title.find(' ')+1); if (begins_with_keyword(tb->title)) b=FXMIN(tb->title.length()-1,tb->title.find(' ')+1); return -comparecase(&ta->title[a],&tb->title[b]); } gogglesmm-0.12.7/src/fxext.cpp0000644000175000001440000017507611525430601014753 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "fxext.h" #include "GMPlayerManager.h" #include "GMPreferences.h" #if FOXVERSION < FXVERSION(1,7,0) #define gm_make_hilite_color makeHiliteColor #define gm_make_shadow_color makeShadowColor #else // Get highlight color static FXColor gm_make_hilite_color(FXColor clr){ FXuint r,g,b; r=FXREDVAL(clr); g=FXGREENVAL(clr); b=FXBLUEVAL(clr); r=FXMAX(31,r); g=FXMAX(31,g); b=FXMAX(31,b); r=(133*r)/100; g=(133*g)/100; b=(133*b)/100; r=FXMIN(255,r); g=FXMIN(255,g); b=FXMIN(255,b); return FXRGB(r,g,b); } // Get shadow color static FXColor gm_make_shadow_color(FXColor clr){ FXuint r,g,b; r=FXREDVAL(clr); g=FXGREENVAL(clr); b=FXBLUEVAL(clr); r=(66*r)/100; g=(66*g)/100; b=(66*b)/100; return FXRGB(r,g,b); } #endif // Fill vertical gradient rectangle void fillVerticalGradient(FXDCWindow & dc,FXint x,FXint y,FXint w,FXint h,FXColor top,FXColor bottom){ register FXint rr,gg,bb,dr,dg,db,r1,g1,b1,r2,g2,b2,yl,yh,yy,dy,n,t; if(0n) n=t; if((t=FXABS(db))>n) n=t; n++; if(n>h) n=h; if(n>128) n=128; rr=(r1<<16)+32767; gg=(g1<<16)+32767; bb=(b1<<16)+32767; yy=32767; dr=(dr<<16)/n; dg=(dg<<16)/n; db=(db<<16)/n; dy=(h<<16)/n; do{ yl=yy>>16; yy+=dy; yh=yy>>16; dc.setForeground(FXRGB(rr>>16,gg>>16,bb>>16)); dc.fillRectangle(x,y+yl,w,yh-yl); rr+=dr; gg+=dg; bb+=db; } while(yhn) n=t; if((t=FXABS(db))>n) n=t; n++; if(n>w) n=w; if(n>128) n=128; rr=(r1<<16)+32767; gg=(g1<<16)+32767; bb=(b1<<16)+32767; xx=32767; dr=(dr<<16)/n; dg=(dg<<16)/n; db=(db<<16)/n; dx=(w<<16)/n; do{ xl=xx>>16; xx+=dx; xh=xx>>16; dc.setForeground(FXRGB(rr>>16,gg>>16,bb>>16)); dc.fillRectangle(x+xl,y,xh-xl,h); rr+=dr; gg+=dg; bb+=db; } while(xhgetShadowColor(); } FXIMPLEMENT(GMScrollHFrame,FXHorizontalFrame,NULL,0) GMScrollHFrame::GMScrollHFrame(){ } GMScrollHFrame::GMScrollHFrame(FXComposite*p):FXHorizontalFrame(p,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_LINE,0,0,0,0,0,0,0,0,0,0){ borderColor=getApp()->getShadowColor(); } FXIMPLEMENT(GMTabFrame,FXVerticalFrame,NULL,0) GMTabFrame::GMTabFrame(){ } GMTabFrame::GMTabFrame(FXComposite*p):FXVerticalFrame(p,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_LINE,0,0,0,0){ borderColor=getApp()->getShadowColor(); } FXIMPLEMENT(GMHeaderItem,FXHeaderItem,NULL,0) // Map FXDEFMAP(GMHeader) GMHeaderMap[]={ FXMAPFUNC(SEL_PAINT,0,GMHeader::onPaint), }; // Object implementation FXIMPLEMENT(GMHeader,FXHeader,GMHeaderMap,ARRAYNUMBER(GMHeaderMap)) // Make a Header GMHeader::GMHeader(){ } // Make a Header GMHeader::GMHeader(FXComposite* p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb): FXHeader(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ } // Handle repaint long GMHeader::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent *ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); register FXint x,y,w,h,i,ilo,ihi; // Set font dc.setFont(font); // Paint background fillVerticalGradient(dc,ev->rect.x,0,ev->rect.w,height-1,gm_make_hilite_color(backColor),gm_make_hilite_color(gm_make_shadow_color(backColor))); dc.setForeground(shadowColor); dc.fillRectangle(ev->rect.x,height-1,ev->rect.w,1); // dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h); // Vertical if(options&HEADER_VERTICAL){ // Determine affected items ilo=getItemAt(ev->rect.y); ihi=getItemAt(ev->rect.y+ev->rect.h); // Fragment below first item if(ilo<0){ y=pos; if(0getPos(); } if(0=items.no()){ y=pos; if(0getPos()+items[items.no()-1]->getSize(); } if(ygetPos(); h=items[i]->getSize(); if(items[i]->isPressed()){ if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,y,width,h); else if(options&FRAME_RAISED) drawSunkenRectangle(dc,0,y,width,h); } else{ if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,y,width,h); else if(options&FRAME_RAISED) drawRaisedRectangle(dc,0,y,width,h); } ((GMHeaderItem*)items[i])->draw(this,dc,0,y,width,h); } } // Horizontal else{ // Determine affected items ilo=getItemAt(ev->rect.x); ihi=getItemAt(ev->rect.x+ev->rect.w); // Fragment below first item if(ilo<0){ x=pos; if(0getPos(); } /* if(0=items.no()){ x=pos; if(0getPos()+items[items.no()-1]->getSize(); } if(xgetPos(); w=items[i]->getSize(); if(items[i]->isPressed()){ if (x>0) { dc.setForeground(hiliteColor); dc.fillRectangle(x,0,1,height); } dc.setForeground(shadowColor); dc.fillRectangle(x+w-1,0,1,height); /* if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,x,0,w,height); else if(options&FRAME_RAISED) drawSunkenRectangle(dc,x,0,w,height); */ } else{ if (x>0) { dc.setForeground(hiliteColor); dc.fillRectangle(x,0,1,height); } dc.setForeground(shadowColor); dc.fillRectangle(x+w-1,0,1,height); /* if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,x,0,w,height); else if(options&FRAME_RAISED) drawRaisedRectangle(dc,x,0,w,height); */ } ((GMHeaderItem*)items[i])->draw(this,dc,x,0,w,height); } } return 1; } FXIMPLEMENT(GMMenuCommand,FXMenuCommand,NULL,0) GMMenuCommand::GMMenuCommand(FXComposite* p,const FXString& text,FXIcon* ic,FXObject* tgt,FXSelector sel,FXuint opts) : FXMenuCommand(p,text,ic,tgt,sel,opts){ backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMMenuCheck,FXMenuCheck,NULL,0) GMMenuCheck::GMMenuCheck(FXComposite* p,const FXString& text,FXObject* tgt,FXSelector sel,FXuint opts) : FXMenuCheck(p,text,tgt,sel,opts){ backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMMenuRadio,FXMenuRadio,NULL,0) GMMenuRadio::GMMenuRadio(FXComposite* p,const FXString& text,FXObject* tgt,FXSelector sel,FXuint opts) : FXMenuRadio(p,text,tgt,sel,opts){ backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMMenuCascade,FXMenuCascade,NULL,0) GMMenuCascade::GMMenuCascade(FXComposite* p,const FXString& text,FXIcon* ic,FXPopup* pup,FXuint opts) : FXMenuCascade(p,text,ic,pup,opts){ backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMMenuPane,FXMenuPane,NULL,0) GMMenuPane::GMMenuPane(FXWindow* owner,FXuint opts) : FXMenuPane(owner,opts) { borderColor=getApp()->getShadowColor(); setFrameStyle(FRAME_LINE); } FXDEFMAP(GMTextField) GMTextFieldMap[]={ FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,GMTextField::onLeftBtnPress) }; FXIMPLEMENT(GMTextField,FXTextField,GMTextFieldMap,ARRAYNUMBER(GMTextFieldMap)) GMTextField::GMTextField(FXComposite* p,FXint ncols,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXTextField(p,ncols,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ borderColor=getApp()->getShadowColor(); setFrameStyle(FRAME_LINE); } FXbool GMTextField::extendWordSelection(FXint pos,FXbool /*notify*/) { register FXint sp,ep; pos=contents.validate(FXCLAMP(0,pos,contents.length())); if(pos<=anchor){ sp=wordStart(pos); ep=wordEnd(anchor); } else{ sp=wordStart(anchor); ep=wordEnd(pos); } return setSelection(sp,ep-sp); } // Pressed left button long GMTextField::onLeftBtnPress(FXObject*,FXSelector,void* ptr){ FXEvent* ev=(FXEvent*)ptr; flags&=~FLAG_TIP; handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr); if(isEnabled()){ grab(); if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) return 1; flags&=~FLAG_UPDATE; if(ev->click_count==1){ setCursorPos(index(ev->win_x)); if(ev->state&SHIFTMASK){ extendSelection(cursor); } else{ killSelection(); setAnchorPos(cursor); } makePositionVisible(cursor); flags|=FLAG_PRESSED; } else if (ev->click_count==2) { setAnchorPos(cursor); extendWordSelection(cursor,true); } else{ setAnchorPos(0); setCursorPos(contents.length()); extendSelection(contents.length()); makePositionVisible(cursor); } return 1; } return 0; } FXIMPLEMENT(GMSpinner,FXSpinner,NULL,0) GMSpinner::GMSpinner(FXComposite* p,FXint ncols,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXSpinner(p,ncols,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ borderColor=getApp()->getShadowColor(); setFrameStyle(FRAME_LINE); upButton->setFrameStyle(FRAME_NONE); downButton->setFrameStyle(FRAME_NONE); upButton->setPadLeft(1); upButton->setPadRight(1); upButton->setPadTop(2); upButton->setPadBottom(2); downButton->setPadLeft(1); downButton->setPadRight(1); downButton->setPadTop(2); downButton->setPadBottom(2); } FXDEFMAP(GMMenuTitle) GMMenuTitleMap[]={ FXMAPFUNC(SEL_PAINT,0,GMMenuTitle::onPaint), FXMAPFUNC(SEL_COMMAND,FXWindow::ID_POST,GMMenuTitle::onCmdPost), }; FXIMPLEMENT(GMMenuTitle,FXMenuTitle,GMMenuTitleMap,ARRAYNUMBER(GMMenuTitleMap)) GMMenuTitle::GMMenuTitle(FXComposite* p,const FXString& text,FXIcon* ic,FXPopup* pup,FXuint opts) : FXMenuTitle(p,text,ic,pup,opts){ selbackColor=getApp()->getSelbackColor(); seltextColor=getApp()->getSelforeColor(); } // Handle repaint long GMMenuTitle::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent *ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); FXint xx,yy; dc.setFont(font); xx=6; yy=0; if(isEnabled()){ if(isActive()){ dc.setForeground(gm_make_shadow_color(selbackColor)); // dc.fillRectangle(0,height-1,width,1); dc.fillRectangle(width-1,0,1,height); dc.fillRectangle(0,0,width,1); dc.fillRectangle(0,0,1,height); dc.setForeground(selbackColor); dc.fillRectangle(1,1,width-2,height-1); xx++; yy++; } else if(underCursor()){ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } if(icon){ dc.drawIcon(icon,xx,yy+(height-icon->getHeight())/2); xx+=5+icon->getWidth(); } if(!label.empty()){ yy+=font->getFontAscent()+(height-font->getFontHeight())/2; dc.setForeground(isActive() ? seltextColor : textColor); dc.drawText(xx,yy,label); if(0<=hotoff){ dc.fillRectangle(xx+font->getTextWidth(&label[0],hotoff),yy+1,font->getTextWidth(&label[hotoff],wclen(&label[hotoff])),1); } } } else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); if(icon){ dc.drawIconSunken(icon,xx,yy+(height-icon->getHeight())/2); xx+=5+icon->getWidth(); } if(!label.empty()){ yy+=font->getFontAscent()+(height-font->getFontHeight())/2; dc.setForeground(hiliteColor); dc.drawText(xx+1,yy+1,label); if(0<=hotoff){ dc.fillRectangle(xx+font->getTextWidth(&label[0],hotoff),yy+1,font->getTextWidth(&label[hotoff],wclen(&label[hotoff])),1); } dc.setForeground(shadowColor); dc.drawText(xx,yy,label); if(0<=hotoff){ dc.fillRectangle(xx+font->getTextWidth(&label[0],hotoff),yy+1,font->getTextWidth(&label[hotoff],wclen(&label[hotoff])),1); } } } return 1; } // Post the menu long GMMenuTitle::onCmdPost(FXObject*,FXSelector,void*){ FXint x,y,side; if(pane && !pane->shown()){ translateCoordinatesTo(x,y,getRoot(),0,0); side=getParent()->getLayoutHints(); if(side&LAYOUT_SIDE_LEFT){ // Vertical //y-=1; if(side&LAYOUT_SIDE_BOTTOM){ // On right x-=pane->getDefaultWidth(); } else{ // On left x+=width; } } else{ // Horizontal //x-=1; if(side&LAYOUT_SIDE_BOTTOM){ // On bottom y-=pane->getDefaultHeight(); } else{ // On top y+=height; } } pane->popup(getParent(),x,y); if(!getParent()->grabbed()) getParent()->grab(); } flags&=~FLAG_UPDATE; flags|=FLAG_ACTIVE; update(); return 1; } FXDEFMAP(GMButton) GMButtonMap[]={ FXMAPFUNC(SEL_PAINT,0,GMButton::onPaint) }; FXIMPLEMENT(GMButton,FXButton,GMButtonMap,ARRAYNUMBER(GMButtonMap)) GMButton::GMButton(){ } GMButton::GMButton(FXComposite* p,const FXString& text,FXIcon* ic,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXButton(p,text,ic,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { } // Handle repaint long GMButton::onPaint(FXObject*,FXSelector,void* ptr){ FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy; FXEvent*ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); // shadowColor = gm_make_shadow_color(baseColor); FXColor top = gm_make_hilite_color(backColor); FXColor bottom = gm_make_hilite_color(shadowColor); FXColor shade = gm_make_hilite_color(shadowColor); FXColor bordercolor = shadowColor; FXPoint basebackground[4]={FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)}; FXPoint bordershade[16]={FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1), FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2), FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2), FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2) }; FXPoint bordercorners[4]={FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)}; if (options&BUTTON_TOOLBAR && (!underCursor() || !isEnabled())) { dc.setForeground(baseColor); dc.fillRectangle(0,0,width,height); } else if (state==STATE_UP && ((options&BUTTON_TOOLBAR)==0 || (options&BUTTON_TOOLBAR && underCursor()))) { /// Outside Background dc.setForeground(baseColor); dc.drawPoints(basebackground,4); /// Border dc.setForeground(bordercolor); dc.drawRectangle(2,0,width-5,0); dc.drawRectangle(2,height-1,width-5,height-1); dc.drawRectangle(0,2,0,height-5); dc.drawRectangle(width-1,2,0,height-5); dc.drawPoints(bordercorners,4); dc.setForeground(shade); dc.drawPoints(bordershade,16); fillVerticalGradient(dc,2,1,width-4,height-2,top,bottom); dc.setForeground(top); dc.drawRectangle(1,3,0,height-7); dc.setForeground(bottom); dc.drawRectangle(width-2,3,0,height-7); } else { /// Outside Background dc.setForeground(baseColor); dc.drawPoints(basebackground,4); /// Border dc.setForeground(bordercolor); dc.drawRectangle(2,0,width-5,0); dc.drawRectangle(2,height-1,width-5,height-1); dc.drawRectangle(0,2,0,height-5); dc.drawRectangle(width-1,2,0,height-5); dc.drawPoints(bordercorners,4); dc.setForeground(shade); dc.drawPoints(bordershade,16); dc.setForeground(baseColor); dc.fillRectangle(2,1,width-4,height-2); //dc.setForeground(FXRGB(0xdc,0xd4,0xc9)); //dc.fillRectangle(2,1,width-4,height-2); } // Place text & icon if(!label.empty()){ tw=labelWidth(label); th=labelHeight(label); } if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); } just_x(tx,ix,tw,iw); just_y(ty,iy,th,ih); // Shift a bit when pressed if(state && (options&(FRAME_RAISED|FRAME_SUNKEN))){ ++tx; ++ty; ++ix; ++iy; } // Draw enabled state if(isEnabled()){ if(icon){ dc.drawIcon(icon,ix,iy); } if(!label.empty()){ dc.setFont(font); dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } if(hasFocus()){ dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2); } } // Draw grayed-out state else{ if(icon){ dc.drawIconSunken(icon,ix,iy); } if(!label.empty()){ dc.setFont(font); dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } return 1; } FXDEFMAP(GMToggleButton) GMToggleButtonMap[]={ FXMAPFUNC(SEL_PAINT,0,GMToggleButton::onPaint) }; FXIMPLEMENT(GMToggleButton,FXToggleButton,GMToggleButtonMap,ARRAYNUMBER(GMToggleButtonMap)) GMToggleButton::GMToggleButton(){ } GMToggleButton::GMToggleButton(FXComposite* p,const FXString& text1,const FXString& text2,FXIcon* ic1,FXIcon* ic2,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXToggleButton(p,text1,text2,ic1,ic2,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { } // Handle repaint long GMToggleButton::onPaint(FXObject*,FXSelector,void* ptr){ FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy; FXEvent *ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); FXColor top = gm_make_hilite_color(backColor); FXColor bottom = gm_make_hilite_color(shadowColor); FXColor shade = gm_make_hilite_color(shadowColor); FXColor bordercolor = shadowColor; FXPoint basebackground[4]={FXPoint(0,0),FXPoint(width-1,0),FXPoint(0,height-1),FXPoint(width-1,height-1)}; FXPoint bordershade[16]={FXPoint(0,1),FXPoint(1,0),FXPoint(1,2),FXPoint(2,1), FXPoint(width-2,0),FXPoint(width-1,1),FXPoint(width-3,1),FXPoint(width-2,2), FXPoint(0,height-2),FXPoint(1,height-1),FXPoint(1,height-3),FXPoint(2,height-2), FXPoint(width-1,height-2),FXPoint(width-2,height-1),FXPoint(width-2,height-3),FXPoint(width-3,height-2) }; FXPoint bordercorners[4]={FXPoint(1,1),FXPoint(1,height-2),FXPoint(width-2,1),FXPoint(width-2,height-2)}; // Got a border at all? if(options&(FRAME_RAISED|FRAME_SUNKEN)){ // Toolbar style if(options&TOGGLEBUTTON_TOOLBAR){ // Enabled and cursor inside and down if(down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)){ /// Outside Background dc.setForeground(baseColor); dc.drawPoints(basebackground,4); /// Border dc.setForeground(bordercolor); dc.drawRectangle(2,0,width-5,0); dc.drawRectangle(2,height-1,width-5,height-1); dc.drawRectangle(0,2,0,height-5); dc.drawRectangle(width-1,2,0,height-5); dc.drawPoints(bordercorners,4); dc.setForeground(shade); dc.drawPoints(bordershade,16); dc.setForeground(baseColor); dc.fillRectangle(2,1,width-4,height-2); } // Enabled and cursor inside, and up else if(isEnabled() && underCursor()){ /// Outside Background dc.setForeground(baseColor); dc.drawPoints(basebackground,4); /// Border dc.setForeground(bordercolor); dc.drawRectangle(2,0,width-5,0); dc.drawRectangle(2,height-1,width-5,height-1); dc.drawRectangle(0,2,0,height-5); dc.drawRectangle(width-1,2,0,height-5); dc.drawPoints(bordercorners,4); dc.setForeground(shade); dc.drawPoints(bordershade,16); fillVerticalGradient(dc,2,1,width-4,height-2,top,bottom); dc.setForeground(top); dc.drawRectangle(1,3,0,height-7); dc.setForeground(bottom); dc.drawRectangle(width-2,3,0,height-7); } // Disabled or unchecked or not under cursor else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } } // Normal style else{ // Draw sunken if pressed if(down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)){ dc.setForeground(hiliteColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } // Draw raised if not currently pressed down else{ dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height); else drawRaisedRectangle(dc,0,0,width,height); } } } // No borders else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } // Place text & icon if(state && !altlabel.empty()){ tw=labelWidth(altlabel); th=labelHeight(altlabel); } else if(!label.empty()){ tw=labelWidth(label); th=labelHeight(label); } if(state && alticon){ iw=alticon->getWidth(); ih=alticon->getHeight(); } else if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); } just_x(tx,ix,tw,iw); just_y(ty,iy,th,ih); // Shift a bit when pressed if((down || ((options&TOGGLEBUTTON_KEEPSTATE) && state)) && (options&(FRAME_RAISED|FRAME_SUNKEN))){ ++tx; ++ty; ++ix; ++iy; } // Draw enabled state if(isEnabled()){ if(state && alticon){ dc.drawIcon(alticon,ix,iy); } else if(icon){ dc.drawIcon(icon,ix,iy); } if(state && !altlabel.empty()){ dc.setFont(font); dc.setForeground(textColor); drawLabel(dc,altlabel,althotoff,tx,ty,tw,th); } else if(!label.empty()){ dc.setFont(font); dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } if(hasFocus()){ dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2); } } // Draw grayed-out state else{ if(state && alticon){ dc.drawIconSunken(alticon,ix,iy); } else if(icon){ dc.drawIconSunken(icon,ix,iy); } if(state && !altlabel.empty()){ dc.setFont(font); dc.setForeground(hiliteColor); drawLabel(dc,altlabel,althotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,altlabel,althotoff,tx,ty,tw,th); } else if(!label.empty()){ dc.setFont(font); dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } return 1; } FXIMPLEMENT(GMRadioButton,FXRadioButton,NULL,0) GMRadioButton::GMRadioButton(){ } GMRadioButton::GMRadioButton(FXComposite* p,const FXString& text,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXRadioButton(p,text,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { // borderColor=getApp()->getShadowColor(); borderColor=getApp()->getBackColor(); hiliteColor=getApp()->getShadowColor(); baseColor=getApp()->getBackColor(); } FXDEFMAP(GMCheckButton) GMCheckButtonMap[]={ FXMAPFUNC(SEL_PAINT,0,GMCheckButton::onPaint) }; FXIMPLEMENT(GMCheckButton,FXCheckButton,GMCheckButtonMap,ARRAYNUMBER(GMCheckButtonMap)) GMCheckButton::GMCheckButton(){ } GMCheckButton::GMCheckButton(FXComposite* p,const FXString& text,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXCheckButton(p,text,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { } long GMCheckButton::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent *ev=(FXEvent*)ptr; FXint tw=0,th=0,tx,ty,ix,iy; FXDCWindow dc(this,ev); // Figure text size if(!label.empty()){ tw=labelWidth(label); th=labelHeight(label); } // Placement just_x(tx,ix,tw,13); just_y(ty,iy,th,13); // Widget background dc.setForeground(backColor); dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h); // Check background if(check==MAYBE || !isEnabled()) dc.setForeground(baseColor); else dc.setForeground(boxColor); dc.fillRectangle(ix+2,iy+2,9,9); // Check border if(options&CHECKBUTTON_PLUS){ dc.setForeground(textColor); dc.drawRectangle(ix+2,iy+2,8,8); } else{ dc.setForeground(shadowColor); dc.drawRectangle(ix+1,iy+1,10,10); } // Check color if(check==MAYBE || !isEnabled()) dc.setForeground(shadowColor); else dc.setForeground(checkColor); // Show as + if(options&CHECKBUTTON_PLUS){ if(check!=TRUE){ dc.fillRectangle(ix+6,iy+4,1,5); } dc.fillRectangle(ix+4,iy+6,5,1); } // Show as v else{ if(check!=FALSE){ FXSegment seg[6]; #ifndef WIN32 seg[0].x1=3+ix; seg[0].y1=5+iy; seg[0].x2=5+ix; seg[0].y2=7+iy; seg[1].x1=3+ix; seg[1].y1=6+iy; seg[1].x2=5+ix; seg[1].y2=8+iy; seg[2].x1=3+ix; seg[2].y1=7+iy; seg[2].x2=5+ix; seg[2].y2=9+iy; seg[3].x1=5+ix; seg[3].y1=7+iy; seg[3].x2=9+ix; seg[3].y2=3+iy; seg[4].x1=5+ix; seg[4].y1=8+iy; seg[4].x2=9+ix; seg[4].y2=4+iy; seg[5].x1=5+ix; seg[5].y1=9+iy; seg[5].x2=9+ix; seg[5].y2=5+iy; #else seg[0].x1=3+ix; seg[0].y1=5+iy; seg[0].x2=5+ix; seg[0].y2=7+iy; seg[1].x1=3+ix; seg[1].y1=6+iy; seg[1].x2=5+ix; seg[1].y2=8+iy; seg[2].x1=3+ix; seg[2].y1=7+iy; seg[2].x2=5+ix; seg[2].y2=9+iy; seg[3].x1=5+ix; seg[3].y1=7+iy; seg[3].x2=10+ix; seg[3].y2=2+iy; seg[4].x1=5+ix; seg[4].y1=8+iy; seg[4].x2=10+ix; seg[4].y2=3+iy; seg[5].x1=5+ix; seg[5].y1=9+iy; seg[5].x2=10+ix; seg[5].y2=4+iy; #endif dc.drawLineSegments(seg,6); } } // Text if(!label.empty()){ dc.setFont(font); if(isEnabled()){ dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); if(hasFocus()){ dc.drawFocusRectangle(tx-1,ty-1,tw+2,th+2); } } else{ dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } // Frame drawFrame(dc,0,0,width,height); return 1; } #define MENUBUTTONARROW_WIDTH 11 #define MENUBUTTONARROW_HEIGHT 5 #define MENUBUTTON_MASK (MENUBUTTON_AUTOGRAY|MENUBUTTON_AUTOHIDE|MENUBUTTON_TOOLBAR|MENUBUTTON_NOARROWS) #define POPUP_MASK (MENUBUTTON_UP|MENUBUTTON_LEFT) #define ATTACH_MASK (MENUBUTTON_ATTACH_RIGHT|MENUBUTTON_ATTACH_CENTER) FXDEFMAP(GMMenuButton) GMMenuButtonMap[]={ FXMAPFUNC(SEL_PAINT,0,GMMenuButton::onPaint) }; FXIMPLEMENT(GMMenuButton,FXMenuButton,GMMenuButtonMap,ARRAYNUMBER(GMMenuButtonMap)) GMMenuButton::GMMenuButton(){ } GMMenuButton::GMMenuButton(FXComposite* p,const FXString& text,FXIcon* ic,FXPopup* pup,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXMenuButton(p,text,ic,pup,opts,x,y,w,h,pl,pr,pt,pb) { } // Handle repaint long GMMenuButton::onPaint(FXObject*,FXSelector,void* ptr){ FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy; FXEvent *ev=(FXEvent*)ptr; FXPoint points[3]; FXDCWindow dc(this,ev); // Got a border at all? if(options&(FRAME_RAISED|FRAME_SUNKEN)){ // Toolbar style if(options&MENUBUTTON_TOOLBAR){ // Enabled and cursor inside, and not popped up if(isEnabled() && underCursor() && !state){ dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height); else drawRaisedRectangle(dc,0,0,width,height); } // Enabled and popped up else if(isEnabled() && state){ dc.setForeground(hiliteColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } // Disabled or unchecked or not under cursor else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } } // Normal style else{ // Draw in up state if disabled or up if(!isEnabled() || !state){ dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height); else drawRaisedRectangle(dc,0,0,width,height); } // Draw sunken if enabled and either checked or pressed else{ dc.setForeground(hiliteColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } } } // No borders else{ if(isEnabled() && state){ dc.setForeground(hiliteColor); dc.fillRectangle(0,0,width,height); } else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } } // Position text & icon // if(!label.empty()){ // tw=labelWidth(label); // th=labelHeight(label); // } // Icon? if(icon){ tw=icon->getWidth(); th=icon->getHeight(); } // Arrows? if(!(options&MENUBUTTON_NOARROWS)){ iw=MENUBUTTONARROW_WIDTH; ih=MENUBUTTONARROW_HEIGHT; } // Keep some room for the arrow! just_x(tx,ix,tw,iw); just_y(ty,iy,th,ih); // Move a bit when pressed if(state){ ++tx; ++ty; ++ix; ++iy; } // Draw icon if(icon){ if(isEnabled()) dc.drawIcon(icon,tx,ty); else dc.drawIconSunken(icon,tx,ty); } // Draw arrows if(!(options&MENUBUTTON_NOARROWS)){ // Right arrow if((options&MENUBUTTON_RIGHT)==MENUBUTTON_RIGHT){ if(isEnabled()) dc.setForeground(textColor); else dc.setForeground(shadowColor); points[0].x=ix; points[0].y=iy; points[1].x=ix; points[1].y=iy+MENUBUTTONARROW_WIDTH-1; points[2].x=ix+MENUBUTTONARROW_HEIGHT; points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1)); dc.fillPolygon(points,3); } // Left arrow else if(options&MENUBUTTON_LEFT){ if(isEnabled()) dc.setForeground(textColor); else dc.setForeground(shadowColor); points[0].x=ix+MENUBUTTONARROW_HEIGHT; points[0].y=iy; points[1].x=ix+MENUBUTTONARROW_HEIGHT; points[1].y=iy+MENUBUTTONARROW_WIDTH-1; points[2].x=ix; points[2].y=(FXshort)(iy+(MENUBUTTONARROW_WIDTH>>1)); dc.fillPolygon(points,3); } // Up arrow else if(options&MENUBUTTON_UP){ if(isEnabled()) dc.setForeground(textColor); else dc.setForeground(shadowColor); points[0].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1)); points[0].y=iy-1; points[1].x=ix; points[1].y=iy+MENUBUTTONARROW_HEIGHT; points[2].x=ix+MENUBUTTONARROW_WIDTH; points[2].y=iy+MENUBUTTONARROW_HEIGHT; dc.fillPolygon(points,3); } // Down arrow else{ if(isEnabled()) dc.setForeground(textColor); else dc.setForeground(shadowColor); points[0].x=ix+1; points[0].y=iy; points[2].x=ix+MENUBUTTONARROW_WIDTH-1; points[2].y=iy; points[1].x=(FXshort)(ix+(MENUBUTTONARROW_WIDTH>>1)); points[1].y=iy+MENUBUTTONARROW_HEIGHT; dc.fillPolygon(points,3); } } // Draw text if(!label.empty()){ dc.setFont(font); if(isEnabled()){ dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } else{ dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } // Draw focus if(hasFocus()){ if(isEnabled()){ dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2); } } return 1; } // Get default width FXint GMMenuButton::getDefaultWidth(){ FXint tw=0,iw=0,s=4,w,pw; // if(!label.empty()){ tw=labelWidth(label); s=4; } if(!(options&MENUBUTTON_NOARROWS)){ if(options&MENUBUTTON_LEFT) iw=MENUBUTTONARROW_HEIGHT; else iw=MENUBUTTONARROW_WIDTH; } if(icon) tw=icon->getWidth(); if(!(options&(ICON_AFTER_TEXT|ICON_BEFORE_TEXT))) w=FXMAX(tw,iw); else w=tw+iw+s; w=padleft+padright+(border<<1)+w; if(!(options&MENUBUTTON_LEFT) && (options&MENUBUTTON_ATTACH_RIGHT) && (options&MENUBUTTON_ATTACH_CENTER)){ if(pane){ pw=pane->getDefaultWidth(); if(pw>w) w=pw; } } return w; } // Get default height FXint GMMenuButton::getDefaultHeight(){ FXint th=0,ih=0,h,ph; // if(!label.empty()){ th=labelHeight(label); } if(!(options&MENUBUTTON_NOARROWS)){ if(options&MENUBUTTON_LEFT) ih=MENUBUTTONARROW_WIDTH; else ih=MENUBUTTONARROW_HEIGHT; } if(icon) th=icon->getHeight(); if(!(options&(ICON_ABOVE_TEXT|ICON_BELOW_TEXT))) h=FXMAX(th,ih); else h=th+ih; h=padtop+padbottom+(border<<1)+h; if((options&MENUBUTTON_LEFT) && (options&MENUBUTTON_ATTACH_BOTTOM) && (options&MENUBUTTON_ATTACH_CENTER)){ if(pane){ ph=pane->getDefaultHeight(); if(ph>h) h=ph; } } return h; } FXDEFMAP(GMHeaderButton) GMHeaderButtonMap[]={ FXMAPFUNC(SEL_PAINT,0,GMHeaderButton::onPaint) }; FXIMPLEMENT(GMHeaderButton,FXButton,GMHeaderButtonMap,ARRAYNUMBER(GMHeaderButtonMap)) GMHeaderButton::GMHeaderButton(){ arrowstate=ARROW_UP; } GMHeaderButton::GMHeaderButton(FXComposite* p,const FXString& text,FXIcon* ic,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXButton(p,text,ic,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { arrowstate=ARROW_UP; } void GMHeaderButton::setArrowState(FXuint s) { arrowstate=s; } FXuint GMHeaderButton::getArrowState() const { return arrowstate; } long GMHeaderButton::onPaint(FXObject*,FXSelector,void*ptr){ FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy; FXEvent *ev=(FXEvent*)ptr; // Start drawing FXDCWindow dc(this,ev); // Got a border at all? if(options&(FRAME_RAISED|FRAME_SUNKEN)){ // Toolbar style if(options&BUTTON_TOOLBAR){ // Enabled and cursor inside, and up if(isEnabled() && underCursor() && (state==STATE_UP)){ dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height); else drawRaisedRectangle(dc,0,0,width,height); } // Enabled and cursor inside and down else if(isEnabled() && underCursor() && (state==STATE_DOWN)){ dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } // Enabled and checked else if(isEnabled() && (state==STATE_ENGAGED)){ dc.setForeground(hiliteColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } // Disabled or unchecked or not under cursor else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } } // Normal style else{ // Default if(isDefault()){ // Draw in up state if disabled or up if(!isEnabled() || (state==STATE_UP)){ dc.setForeground(backColor); dc.fillRectangle(border+1,border+1,width-border*2-1,height-border*2-1); dc.setForeground(FXRGB(255,255,255)); dc.fillRectangle(width-2,1,1,height-1); // if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,1,1,width-1,height-1); // else drawRaisedRectangle(dc,1,1,width-3,height-1); } // Draw sunken if enabled and either checked or pressed else{ if(state==STATE_ENGAGED) dc.setForeground(hiliteColor); else dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2-1,height-border*2-1); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width-1,height-1); else drawSunkenRectangle(dc,0,0,width-1,height-1); } // Black default border drawBorderRectangle(dc,0,0,width,height); } // Non-Default else{ // Draw in up state if disabled or up if(!isEnabled() || (state==STATE_UP)){ dc.setForeground(backColor); //dc.fillRectangle(border,border,width-border*2,height-border*2); //fillVerticalGradient(dc,border,border,width-border*2,height-border*2,makeHiliteColor(makeHiliteColor(makeShadowColor(backColor))),makeHiliteColor(makeShadowColor(backColor))); // fillVerticalGradient(dc,0,0,width,height-1,makeHiliteColor(makeHiliteColor(makeShadowColor(backColor))),makeHiliteColor(makeShadowColor(backColor))); fillVerticalGradient(dc,ev->rect.x,0,ev->rect.w,height-1,gm_make_hilite_color(backColor),gm_make_hilite_color(gm_make_shadow_color(backColor))); dc.setForeground(shadowColor); dc.fillRectangle(0,height-1,width,1); // if(options&FRAME_THICK) drawDoubleRaisedRectangle(dc,0,0,width,height); /// else drawRaisedRectangle(dc,0,0,width-1,height); // dc.setForeground(backColor); // dc.fillRectangle(width-2,0,2,height-1); } // Draw sunken if enabled and either checked or pressed else{ if(state==STATE_ENGAGED) dc.setForeground(hiliteColor); else dc.setForeground(backColor); dc.fillRectangle(border,border,width-border*2,height-border*2); if(options&FRAME_THICK) drawDoubleSunkenRectangle(dc,0,0,width,height); else drawSunkenRectangle(dc,0,0,width,height); } } } } // No borders else{ if(isEnabled() && (state==STATE_ENGAGED)){ dc.setForeground(hiliteColor); dc.fillRectangle(0,0,width,height); } else{ dc.setForeground(backColor); dc.fillRectangle(0,0,width,height); } } // Place text & icon if(!label.empty()){ tw=labelWidth(label); th=labelHeight(label); } if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); } just_x(tx,ix,tw,iw); just_y(ty,iy,th,ih); // Shift a bit when pressed if(state && (options&(FRAME_RAISED|FRAME_SUNKEN))){ ++tx; ++ty; ++ix; ++iy; } // Draw enabled state if(isEnabled()){ if(icon){ dc.drawIcon(icon,ix,iy); } if(!label.empty()){ dc.setFont(font); dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } // if(hasFocus()){ // dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2); // } } // Draw grayed-out state else{ if(icon){ dc.drawIconSunken(icon,ix,iy); } if(!label.empty()){ dc.setFont(font); dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } // Draw arrows if(arrowstate&(ARROW_UP|ARROW_DOWN)){ FXint aa=(font->getFontHeight()-5)|1; FXint ay=(height-aa)/2; FXint ax=width-aa-border-border-2; if(arrowstate&ARROW_UP){ dc.setForeground(hiliteColor); dc.drawLine(ax+aa/2,ay,ax+aa-1,ay+aa); dc.drawLine(ax,ay+aa,ax+aa,ay+aa); dc.setForeground(shadowColor); dc.drawLine(ax+aa/2,ay,ax,ay+aa); } else{ dc.setForeground(hiliteColor); dc.drawLine(ax+aa/2,ay+aa,ax+aa-1,ay); dc.setForeground(shadowColor); dc.drawLine(ax+aa/2,ay+aa,ax,ay); dc.drawLine(ax,ay,ax+aa,ay); } } return 1; } FXIMPLEMENT(GMScrollArea,FXScrollArea,NULL,0) void GMScrollArea::replaceScrollbars(FXScrollArea *fs) { GMScrollArea * s = (GMScrollArea*)(fs); delete s->vertical; delete s->horizontal; delete s->corner; s->vertical=new GMScrollBar(fs,fs,GMScrollArea::ID_VSCROLLED,SCROLLBAR_VERTICAL); s->horizontal=new GMScrollBar(fs,fs,GMScrollArea::ID_HSCROLLED,SCROLLBAR_HORIZONTAL); s->corner=new GMScrollCorner(fs); } FXIMPLEMENT(GMTreeListBox,FXTreeListBox,NULL,0) void GMTreeListBox::replace(FXTreeListBox *fs) { GMTreeListBox * s = (GMTreeListBox*)(fs); GMScrollArea::replaceScrollbars(s->tree); s->borderColor=s->getApp()->getShadowColor(); s->setFrameStyle(FRAME_LINE); s->pane->setBorderColor(s->borderColor); s->button->setFrameStyle(FRAME_NONE); s->button->setPadLeft(2); s->button->setPadRight(2); s->button->setYOffset(0); s->button->setXOffset(1); } // Map FXDEFMAP(GMScrollBar) GMScrollBarMap[]={ FXMAPFUNC(SEL_PAINT,0,GMScrollBar::onPaint), }; // Object implementation FXIMPLEMENT(GMScrollBar,FXScrollBar,GMScrollBarMap,ARRAYNUMBER(GMScrollBarMap)) // For deserialization GMScrollBar::GMScrollBar(){ } // Make a scrollbar GMScrollBar::GMScrollBar(FXComposite* p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h): FXScrollBar(p,tgt,sel,opts,x,y,w,h) { //shadowColor=gm_make_shadow_color(getApp()->getBaseColor()); } void GMScrollBar::drawThumb(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h){ if(options&SCROLLBAR_HORIZONTAL){ fillVerticalGradient(dc,x+2,y,w-4,h-1,gm_make_hilite_color(FXApp::instance()->getSelbackColor()),gm_make_hilite_color(gm_make_shadow_color(FXApp::instance()->getSelbackColor()))); dc.setForeground(shadowColor); dc.fillRectangle(x+w-1,y,1,h); dc.fillRectangle(x,y,1,h); dc.setForeground(gm_make_hilite_color(getApp()->getSelbackColor())); dc.fillRectangle(x+1,y+h-1,w-2,1); dc.fillRectangle(x+w-2,y,1,h-1); dc.fillRectangle(x+1,y,1,h-1); if (w>20) { dc.setForeground(gm_make_shadow_color(getApp()->getSelbackColor())); dc.fillRectangle(thumbpos+thumbsize / 2,(height/2) - 2,1,6); dc.fillRectangle((thumbpos+thumbsize / 2) - 3,(height/2) - 2,1,6); dc.fillRectangle((thumbpos+thumbsize / 2) + 3,(height/2) - 2,1,6); } } else { fillHorizontalGradient(dc,x,y+2,w-1,h-4,gm_make_hilite_color(getApp()->getSelbackColor()),gm_make_hilite_color(gm_make_shadow_color(getApp()->getSelbackColor()))); dc.setForeground(shadowColor); dc.fillRectangle(x,y+h-1,w,1); dc.fillRectangle(x,y,w,1); dc.setForeground(gm_make_hilite_color(getApp()->getSelbackColor())); dc.fillRectangle(x+w-1,y+1,1,h-2); dc.fillRectangle(x,y+1,w-1,1); dc.fillRectangle(x,y+h-2,w-1,1); if (h>20) { dc.setForeground(gm_make_shadow_color(getApp()->getSelbackColor())); dc.fillRectangle((width/2) - 2,thumbpos+thumbsize / 2,6,1); dc.fillRectangle((width/2) - 2,(thumbpos+thumbsize / 2) - 3,6,1); dc.fillRectangle((width/2) - 2,(thumbpos+thumbsize / 2) + 3,6,1); } } } // Handle repaint long GMScrollBar::onPaint(FXObject*,FXSelector,void* ptr){ register FXEvent *ev=(FXEvent*)ptr; register int total; FXDCWindow dc(this,ev); if(options&SCROLLBAR_HORIZONTAL){ total=width-height-height; dc.setForeground(shadowColor); dc.fillRectangle(0,0,width,1); if(thumbsize0) { dc.setForeground(shadowColor); dc.fillRectangle(height,1,1,height-1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(height+1,1,thumbpos-height-1,height-1); } if (width-height-thumbpos-thumbsize>0) { dc.setForeground(shadowColor); dc.fillRectangle(width-height-1,1,1,height-1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(thumbpos+thumbsize,1,width-height-thumbpos-thumbsize-1,height); } } else{ // Non-scrollable dc.fillRectangle(height,1,1,height-1); dc.fillRectangle(width-height-1,1,1,height-1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(height+1,1,total-2,height-1); } dc.setFillStyle(FILL_SOLID); dc.setForeground(backColor); dc.fillRectangle(width-height,1,height,height-1); drawRightArrow(dc,width-height,0,height,height,(mode==MODE_INC)); dc.setForeground(backColor); dc.fillRectangle(0,1,height,height-1); drawLeftArrow(dc,0,0,height,height,(mode==MODE_DEC)); } else{ total=height-width-width; dc.setForeground(shadowColor); dc.fillRectangle(0,0,1,height); if(thumbsize0) { dc.setForeground(shadowColor); dc.fillRectangle(1,width,width-1,1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(1,width+1,width-1,thumbpos-width-1); } if (height-width-thumbpos-thumbsize>0){ dc.setForeground(shadowColor); dc.fillRectangle(1,height-width-1,width-1,1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(1,thumbpos+thumbsize,width-1,height-width-thumbpos-thumbsize-1); } } else{ // Non-scrollable dc.fillRectangle(1,width,width-1,1); dc.fillRectangle(1,height-width-1,width-1,1); dc.setForeground(gm_make_hilite_color(shadowColor)); dc.fillRectangle(1,width+1,width-1,total-2); } dc.setFillStyle(FILL_SOLID); dc.setForeground(backColor); dc.fillRectangle(1,height-width,width-1,width); drawDownArrow(dc,0,height-width,width,width,(mode==MODE_INC)); dc.setForeground(backColor); dc.fillRectangle(1,0,width-1,width); drawUpArrow(dc,0,0,width,width,(mode==MODE_DEC)); } return 1; } // Map FXDEFMAP(GMScrollCorner) GMScrollCornerMap[]={ FXMAPFUNC(SEL_PAINT,0,GMScrollCorner::onPaint), }; FXIMPLEMENT(GMScrollCorner,FXScrollCorner,GMScrollCornerMap,ARRAYNUMBER(GMScrollCornerMap)) GMScrollCorner::GMScrollCorner(FXComposite*p):FXScrollCorner(p){ shadowColor=getApp()->getShadowColor(); } // Slightly different from Frame border long GMScrollCorner::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent *ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); dc.setForeground(backColor); dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h); dc.setForeground(shadowColor); dc.fillRectangle(ev->rect.x,0,ev->rect.w,1); dc.fillRectangle(0,ev->rect.y,1,ev->rect.h); return 1; } FXIMPLEMENT(GMTabBook,FXTabBook,NULL,0) GMTabBook::GMTabBook(FXComposite* p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXTabBook(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { } /// Make sure old tab gets repainted void GMTabBook::setCurrent(FXint panel,FXbool notify) { if (panel!=current) { FXint old = current; FXTabBook::setCurrent(panel,notify); FXWindow * window = childAtIndex(old<<1); if (window) { window->update(); } } } // Map FXDEFMAP(GMTabItem) GMTabItemMap[]={ FXMAPFUNC(SEL_PAINT,0,GMTabItem::onPaint), }; FXIMPLEMENT(GMTabItem,FXTabItem,GMTabItemMap,ARRAYNUMBER(GMTabItemMap)) GMTabItem::GMTabItem(FXTabBar* p,const FXString& text,FXIcon* ic,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint /*pt*/,FXint /*pb*/) : FXTabItem(p,text,ic,opts,x,y,w,h,pl,pr,5,5) { } //void GMTabItem::raise() { // FXTabItem::raise(); // update(); // recalc(); // } long GMTabItem::onPaint(FXObject*,FXSelector,void*){ FXTabBar * bar = (FXTabBar*)getParent(); FXint tab = bar->indexOfChild(this)/2; FXint ntabs = (bar->numChildren()/2); FXint ctab = bar->getCurrent(); FXDCWindow dc(this); FXint tw=0,th=0,iw=0,ih=0,tx,ty,ix,iy; dc.setForeground(shadowColor); dc.fillRectangle(0,0,width,1); if (tab==ctab && tab==0) dc.fillRectangle(0,0,1,height); else dc.fillRectangle(0,0,1,height-1); /// last one or active one if ((tab == (ntabs-1)) || tab==ctab) { dc.fillRectangle(width-1,0,1,height-1); if (tab!=ctab) fillVerticalGradient(dc,1,1,width-2,height-2,gm_make_hilite_color(shadowColor),gm_make_hilite_color(shadowColor)); else { /* dc.setForeground(makeShadowColor(getApp()->getSelbackColor())); dc.fillRectangle(0,0,width,1); dc.fillRectangle(width-1,0,1,4); dc.fillRectangle(0,0,1,4); dc.fillRectangle(1,3,width-2,1); */ /* dc.setForeground(getApp()->getSelbackColor()); dc.fillRectangle(1,1,width-2,2); */ // dc.setForeground(backColor); // dc.fillRectangle(1,4,width-2,height-4); dc.setForeground(getApp()->getSelbackColor()); // dc.fillRectangle(1,1,width-2,height-2); fillVerticalGradient(dc,1,1,width-2,height-2,gm_make_hilite_color(backColor),backColor); dc.setForeground(backColor); if (tab==0) dc.fillRectangle(1,height-1,width-1,height-1); else dc.fillRectangle(0,height-1,width,height-1); } } else { fillVerticalGradient(dc,1,1,width-1,height-2,gm_make_hilite_color(shadowColor),gm_make_hilite_color(shadowColor)); } if(!label.empty()){ tw=labelWidth(label); th=labelHeight(label); } if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); } just_x(tx,ix,tw,iw); just_y(ty,iy,th,ih); if(icon){ if(isEnabled()) dc.drawIcon(icon,ix,iy); else dc.drawIconSunken(icon,ix,iy); } if(!label.empty()){ dc.setFont(font); if(isEnabled()){ dc.setForeground(textColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); if(hasFocus()){ dc.drawFocusRectangle(border+1,border+1,width-2*border-2,height-2*border-2); } } else{ dc.setForeground(hiliteColor); drawLabel(dc,label,hotoff,tx+1,ty+1,tw,th); dc.setForeground(shadowColor); drawLabel(dc,label,hotoff,tx,ty,tw,th); } } return 1; } FXIMPLEMENT(GMListBox,FXListBox,NULL,0); GMListBox::GMListBox(){ } GMListBox::GMListBox(FXComposite*p,FXObject*tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) : FXListBox(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb) { borderColor=getApp()->getShadowColor(); setFrameStyle(FRAME_LINE); GMScrollArea::replaceScrollbars(list); pane->setBorderColor(borderColor); button->setFrameStyle(FRAME_NONE); button->setPadLeft(2); button->setPadRight(2); button->setYOffset(0); button->setXOffset(1); } void GMListBox::create(){ FXListBox::create(); ewmh_change_window_type(pane,WINDOWTYPE_COMBO); } FXIMPLEMENT(GMComboBox,FXComboBox,NULL,0); GMComboBox::GMComboBox(){ } GMComboBox::GMComboBox(FXComposite *p,FXint cols,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) :FXComboBox(p,cols,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ borderColor=getApp()->getShadowColor(); setFrameStyle(FRAME_LINE); pane->setBorderColor(borderColor); GMScrollArea::replaceScrollbars(list); button->setFrameStyle(FRAME_NONE); button->setPadLeft(2); button->setPadRight(2); button->setYOffset(0); button->setXOffset(1); } void GMComboBox::create(){ FXComboBox::create(); ewmh_change_window_type(pane,WINDOWTYPE_COMBO); } FXIMPLEMENT(GMImageFrame,FXImageFrame,NULL,0); GMImageFrame::GMImageFrame(){ } GMImageFrame::GMImageFrame(FXComposite *p,FXImage * img,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) :FXImageFrame(p,img,opts,x,y,w,h,pl,pr,pt,pb){ borderColor=getApp()->getShadowColor(); backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMCoverFrame,FXVerticalFrame,NULL,0); GMCoverFrame::GMCoverFrame(){ } GMCoverFrame::GMCoverFrame(FXComposite *p) :FXVerticalFrame(p,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_LINE,0,0,0,0,5,5,5,5){ borderColor=getApp()->getShadowColor(); backColor=getApp()->getBackColor(); } FXIMPLEMENT(GMProgressBar,FXProgressBar,NULL,0); GMProgressBar::GMProgressBar(){ } GMProgressBar::GMProgressBar(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) :FXProgressBar(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ borderColor=getApp()->getShadowColor(); barColor=getApp()->getSelbackColor(); textAltColor=getApp()->getSelforeColor();//FXRGB(255,255,255); setFrameStyle(FRAME_LINE); } #if 0 FXDEFMAP(GMTrackProgressBar) GMTrackProgressBarMap[]={ FXMAPFUNC(SEL_MOTION,0,GMTrackProgressBar::onMotion), FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,GMTrackProgressBar::onLeftBtnPress), FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,GMTrackProgressBar::onLeftBtnRelease) }; FXIMPLEMENT(GMTrackProgressBar,FXProgressBar,GMTrackProgressBarMap,ARRAYNUMBER(GMTrackProgressBarMap)); GMTrackProgressBar::GMTrackProgressBar(){ flags|=FLAG_ENABLED; } GMTrackProgressBar::GMTrackProgressBar(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb) :FXProgressBar(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){ flags|=FLAG_ENABLED; borderColor=getApp()->getShadowColor(); barColor=getApp()->getSelbackColor(); textAltColor=getApp()->getSelforeColor(); setFrameStyle(FRAME_LINE); } // Moving long GMTrackProgressBar::onMotion(FXObject*,FXSelector,void* ptr){ register FXEvent *event=(FXEvent*)ptr; register FXint xx,yy,ww,hh,lo,hi,p,h,travel; if(!isEnabled()) return 0; if(flags&FLAG_PRESSED){ yy=border+padtop; xx=border+padleft; hh=height-(border<<1)-padtop-padbottom; ww=width-(border<<1)-padleft-padright; /* if(options&PROGRESSBAR_VERTICAL){ h=event->win_y-dragpoint; travel=hh-headsize; if(hyy+travel) h=yy+travel; if(h!=headpos){ FXMINMAX(lo,hi,headpos,h); headpos=h; update(border,lo-1,width-(border<<1),hi+headsize+2-lo); } if(travel>0) p=range[0]+((range[1]-range[0])*(yy+travel-h)+travel/2)/travel; // Use rounding!! else p=range[0]; } else{ h=event->win_x-dragpoint; travel=ww-headsize; if(hxx+travel) h=xx+travel; if(h!=headpos){ FXMINMAX(lo,hi,headpos,h); headpos=h; update(lo-1,border,hi+headsize+2-lo,height-(border<<1)); } if(travel>0) p=range[0]+((range[1]-range[0])*(h-xx)+travel/2)/travel; // Use rounding!! else p=range[0]; } if(prange[1]) p=range[1]; if(pos!=p){ pos=p; flags|=FLAG_CHANGED; if(target) target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)pos); } */ if(progress!=p){ progress=p; flags|=FLAG_CHANGED; if(target) target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)progress); } return 1; } return 0; } // Pressed LEFT button long GMTrackProgressBar::onLeftBtnPress(FXObject*,FXSelector,void* ptr){ fxmessage("press\n"); register FXEvent *event=(FXEvent*)ptr; register FXint p=progress; flags&=~FLAG_TIP; handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr); if(isEnabled()){ grab(); if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) return 1; flags&=~FLAG_UPDATE; /* if(options&PROGRESSBAR_VERTICAL){ if(event->win_ywin_y>(headpos+headsize)){ p=progress-incr; } else{ dragpoint=event->win_y-headpos; flags|=FLAG_PRESSED; } } else{ if(event->win_xwin_x>(headpos+headsize)){ p=progress+incr; } else{ dragpoint=event->win_x-headpos; flags|=FLAG_PRESSED; } } */ // if(prange[1]) p=range[1]; if(p!=progress){ setProgress(p); flags|=FLAG_CHANGED; if(target) target->tryHandle(this,FXSEL(SEL_CHANGED,message),(void*)(FXival)progress); } return 1; } return 0; } // Released Left button long GMTrackProgressBar::onLeftBtnRelease(FXObject*,FXSelector,void* ptr){ register FXEvent *event=(FXEvent*)ptr; fxmessage("release\n"); register FXuint flgs=flags; if(isEnabled()){ ungrab(); FXint xx=border+padleft; FXint ww=width-(border<<1)-padleft-padright; // setProgress(progress); // Hop to exact position flags&=~FLAG_PRESSED; flags&=~FLAG_CHANGED; flags|=FLAG_UPDATE; if(target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) return 1; if (event->click_x > xx && event->click_x < xx+ww) { FXdouble pos = (event->click_x - xx) / (FXdouble)ww; if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),&pos); } return 1; } return 0; } #endif FXIMPLEMENT(GMSettings,FXSettings,NULL,0); #if FOXVERSION < FXVERSION(1,7,0) // Parse filename FXbool GMSettings::parseFile(const FXString& filename,FXbool mrk){ FXFile file(filename,FXIO::Reading); if(file.isOpen()){ // Prepare buffer string FXString string('\0',file.size()); // Load file if(file.readBlock((void*)string.text(),string.length())==string.length()){ FXStringDict *group=NULL; FXint lineno=1,p=0,b,e; FXString name; FXString value; // Skip BOM, if any if(string[p]=='\xef' && string[p+1]=='\xbb' && string[p+2]=='\xbf') p+=3; // Parse one line at a time while(string[p]){ // Skip leading blanks while(Ascii::isBlank(string[p])) p++; // Non-comment if(string[p] && string[p]!='\n' && string[p]!='\r' && string[p]!='#' && string[p]!=';'){ // Parse section name if(string[p]=='['){ b=++p; // Scan section name while(string[p] && string[p]!=']' && string[p]!='\n' && string[p]!='\r' && !Ascii::isControl(string[p])) p++; // Check errors if(string[p]!=']'){ fxwarning("%s:%d: illegal section name.\n",filename.text(),lineno); goto next; } e=p++; // Grab name name=string.mid(b,e-b); // Add new section dict group=insert(name.text()); } // Parse name-value pair else{ // Should have seen section prior to this if(!group){ fxwarning("%s:%d: settings entry should follow a section.\n",filename.text(),lineno); goto next; } b=p; // Scan key name while(string[p] && string[p]!='=' && string[p]!='\n' && string[p]!='\r' && !Ascii::isControl(string[p])) p++; // Check errors if(string[p]!='='){ fxwarning("%s:%d: expected '=' to follow key.\n",filename.text(),lineno); goto next; } e=p++; // Remove trailing spaces after name while(breplace(name.text(),value.text(),mrk); } } // Skip to end of line next: while(string[p] && string[p]!='\n') p++; // End of line if(string[p]=='\n'){ lineno++; p++; } } return true; } } return false; } #endif gogglesmm-0.12.7/src/GMCoverCache.cpp0000644000175000001440000002375411714632017016043 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "gmutils.h" #include "GMTaskManager.h" //#include "GMTrack.h" #include "GMApp.h" //#include "GMCover.h" #include "GMTag.h" #include "GMList.h" #include "GMTrackList.h" #include "GMSource.h" #include "GMTrackView.h" #include "GMTrackDatabase.h" #include "GMPlayerManager.h" #include "GMIconTheme.h" #include "GMCoverCache.h" void FXIntMap::save(FXStream & store) const { store << no(); for (FXuint i=0;i> no; for (FXint i=0;i> key; store >> value; insert(key,value); } } class GMCompressedImage { public: FXuchar * buffer; FXuval len; public: GMCompressedImage() : buffer(NULL),len(0){} GMCompressedImage(FXuchar * b,FXuval l) : len(l) { allocElms(buffer,len); memcpy(buffer,b,len); } void make(FXImage * img) { FXint ww,hh,dd; FXColor * data=NULL; FXMemoryStream ms(FXStreamLoad,buffer,len,false); fxloadJPG(ms,data,ww,hh,dd); ms.close(); FXASSERT(ww==128); FXASSERT(hh==128); img->setData(data,IMAGE_OWNED); img->render(); } ~GMCompressedImage() { freeElms(buffer); } void load(FXStream & store) { store >> len; allocElms(buffer,len); store.load(buffer,len); } void save(FXStream & store) const { store << len; store.save(buffer,len); } }; class CoverLoader: public GMTask { protected: FXuchar * compress_buffer; FXuval compress_buffer_length; FXuval total_c; FXuval total_u; public: GMAlbumPathList albums; GMCoverCache cache; protected: GMCompressedImage* compress(FXColor*,FXint,FXint); GMCompressedImage* compress(FXImage*); GMCompressedImage* compress_fit(FXImage*); FXint run(); public: CoverLoader(GMAlbumPathList & l,FXint sz,FXObject *tgt=NULL,FXSelector sel=0); ~CoverLoader(); }; CoverLoader::CoverLoader(GMAlbumPathList & list,FXint sz,FXObject * tgt,FXSelector sel) : GMTask(tgt,sel), cache(sz) { albums.adopt(list); compress_buffer=NULL; compress_buffer_length=0; } CoverLoader::~CoverLoader(){ freeElms(compress_buffer); } FXint CoverLoader::run() { FXdouble fraction; GMCover * cover=NULL; for (FXint i=0;isetStatus(FXString::value("Loading Covers %d%%",(FXint)(100.0*fraction))); cover = GMCover::fromTag(albums[i].path); if (cover==NULL) cover = GMCover::fromPath(FXPath::directory(albums[i].path)); if (cover) { cache.insertCover(albums[i].id,compress(GMCover::toImage(cover,cache.getCoverSize(),1))); } else { cache.insertCover(albums[i].id,NULL); } } if (processing) cache.save(); return 0; } GMCompressedImage * CoverLoader::compress_fit(FXImage*img) { FXint size = cache.getCoverSize(); FXColor * pix=NULL; allocElms(pix,size*size); memset(pix,255,4*size*size); FXuchar * dst = (FXuchar*)pix; FXuchar * src = (FXuchar*)img->getData(); FXint sw=img->getWidth()*4; FXint sh=img->getHeight(); if (img->getHeight()getHeight())>>1); if (img->getWidth()getWidth())>>1); do { memcpy(dst,src,sw); dst+=size*4; src+=sw; } while(--sh); GMCompressedImage * c = compress(pix,size,size); freeElms(pix); return c; } GMCompressedImage * CoverLoader::compress(FXColor*pix,FXint width,FXint height){ FXMemoryStream ms(FXStreamSave,compress_buffer,compress_buffer_length,true); fxsaveJPG(ms,pix,width,height,75); ms.takeBuffer(compress_buffer,compress_buffer_length); ms.close(); return new GMCompressedImage(compress_buffer,ms.position()); } GMCompressedImage * CoverLoader::compress(FXImage*img) { GMCompressedImage * cimage = NULL; if (img->getWidth()!=cache.getCoverSize() || img->getHeight()!=cache.getCoverSize()) { cimage = compress_fit(img); } else { cimage = compress(img->getData(),cache.getCoverSize(),cache.getCoverSize()); } delete img; return cimage; } FXDEFMAP(GMCoverCache) GMCoverCacheMap[]={ FXMAPFUNC(SEL_TASK_COMPLETED,GMCoverCache::ID_COVER_LOADER,GMCoverCache::onCmdCoversLoaded), }; FXIMPLEMENT(GMCoverCache,FXObject,GMCoverCacheMap,ARRAYNUMBER(GMCoverCacheMap)); GMCoverCache::GMCoverCache(FXint size) : basesize(size),initialized(false) { } GMCoverCache::~GMCoverCache() { for (FXint i=0;i0) { FXImage * image = getCoverImage(id); dc.drawImage(image,x,y); return; } else { FXIcon * ic = GMIconTheme::instance()->icon_nocover; if (ic->getHeight()getHeight())>>1; if (ic->getWidth()getWidth())>>1; dc.drawIcon(ic,x,y); } } void GMCoverCache::insertCover(FXint id,GMCompressedImage * image) { if (image) { covers.append(image); map.insert(id,covers.no()); } } void GMCoverCache::markCover(FXint id) { for (FXint i=0,index;igetUserData(); if (index==-id) { buffers[i]->setUserData((void*)(FXival)id); break; } } } void GMCoverCache::reset() { for (FXint i=0,index;igetUserData(); buffers[i]->setUserData((void*)(FXival)-index); } } FXImage* GMCoverCache::getCoverImage(FXint id) { FXint i,index; FXImage * image=NULL; /// existing for (i=0;igetUserData(); if (index==id) return buffers[i]; } /// find empty for (i=0;igetUserData(); if (index<0) { buffers[i]->setUserData((void*)(FXival)id); image=buffers[i]; break; } } /// Create new one if (image==NULL) { image = new FXImage(FXApp::instance(),NULL,0,basesize,basesize); image->setUserData((void*)(FXival)id); image->create(); buffers.append(image); } index = map.find(id); covers[index-1]->make(image); return image; } void GMCoverCache::init(GMTrackDatabase * database){ if (!initialized && !load()) { refresh(database); } } void GMCoverCache::refresh(GMTrackDatabase * database){ /// Remove the cache file. if (FXStat::exists(getCacheFile())) FXFile::remove(getCacheFile()); /// Only scan for covers if needed if (initialized) { GMAlbumPathList list; database->listAlbumPaths(list); if (list.no()){ CoverLoader * task = new CoverLoader(list,basesize,this,ID_COVER_LOADER); GMPlayerManager::instance()->runTask(task); } } } #define COVERTHUMBS_CACHE_FILE_VERSION 20110920 void GMCoverCache::save() const { const FXuint version=COVERTHUMBS_CACHE_FILE_VERSION; FXFileStream store; if (store.open(getCacheFile(),FXStreamSave)){ store << version; store << basesize; map.save(store); store << (FXint)covers.no(); for (FXint i=0;isave(store); } } } FXbool GMCoverCache::load() { GM_TICKS_START(); initialized=true; FXFileStream store; if (store.open(getCacheFile(),FXStreamLoad)) { FXint no,size; FXuint version; store >> version; if (version!=COVERTHUMBS_CACHE_FILE_VERSION) return false; store >> size; if (basesize!=size) return false; map.load(store); store >> no; for (FXint i=0;iload(store); covers.append(cover); } return true; } GM_TICKS_END(); return false; } long GMCoverCache::onCmdCoversLoaded(FXObject*,FXSelector,void*ptr){ CoverLoader * task = reinterpret_cast(*((void**)ptr)); adopt(task->cache); delete task; GMPlayerManager::instance()->getTrackView()->redrawAlbumList(); return 1; } gogglesmm-0.12.7/src/GMAnimImage.cpp0000644000175000001440000000776211525430601015664 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include "gmdefs.h" #include "GMAnimImage.h" FXDEFMAP(GMAnimImage) GMAnimImageMap[]={ FXMAPFUNC(SEL_PAINT,0,GMAnimImage::onPaint), FXMAPFUNC(SEL_TIMEOUT,GMAnimImage::ID_TIMER,GMAnimImage::onTimer) }; FXIMPLEMENT(GMAnimImage,FXImageFrame,GMAnimImageMap,ARRAYNUMBER(GMAnimImageMap)) GMAnimImage::GMAnimImage(){ index=1; imgw=imgh=32; nrow=8; ncol=4; } // Construct it GMAnimImage::GMAnimImage(FXComposite* p,FXImage *img,FXint base,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb):FXImageFrame(p,img,opts,x,y,w,h,pl,pr,pt,pb){ index=1; imgw=imgh=base; if (img) { nrow=img->getWidth()/imgw; ncol=img->getHeight()/imgh; } else { nrow=1; ncol=1; } } GMAnimImage::~GMAnimImage(){ getApp()->removeTimeout(this,ID_TIMER); } void GMAnimImage::show() { FXImageFrame::show(); } void GMAnimImage::hide() { FXImageFrame::hide(); } void GMAnimImage::create() { FXImageFrame::create(); getApp()->addTimeout(this,ID_TIMER,TIME_MSEC(50)); } // Get default width FXint GMAnimImage::getDefaultWidth(){ register FXint w=0; if(image) w=imgw; return w+padleft+padright+(border<<1); } // Get default height FXint GMAnimImage::getDefaultHeight(){ register FXint h=0; if(image) h=imgh; return h+padtop+padbottom+(border<<1); } long GMAnimImage::onTimer(FXObject*,FXSelector,void*){ if (index==((nrow*ncol)-1)) index=1; else index++; update(); getApp()->addTimeout(this,ID_TIMER,TIME_MSEC(100)); return 0; } // Draw the image long GMAnimImage::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent *ev=(FXEvent*)ptr; FXDCWindow dc(this,ev); FXint imgx,imgy; dc.setForeground(backColor); if(image){ if(options&JUSTIFY_LEFT) imgx=padleft+border; else if(options&JUSTIFY_RIGHT) imgx=width-padright-border-imgw; else imgx=border+padleft+(width-padleft-padright-(border<<1)-imgw)/2; if(options&JUSTIFY_TOP) imgy=padtop+border; else if(options&JUSTIFY_BOTTOM) imgy=height-padbottom-border-imgh; else imgy=border+padtop+(height-padbottom-padtop-(border<<1)-imgh)/2; dc.fillRectangle(border,border,imgx-border,height-(border<<1)); dc.fillRectangle(imgx+imgw,border,width-border-imgx-imgw,height-(border<<1)); dc.fillRectangle(imgx,border,imgw,imgy-border); dc.fillRectangle(imgx,imgy+imgh,imgw,height-border-imgy-imgh); dc.drawArea(image,(index%nrow)*imgw,(index/nrow)*imgh,imgw,imgh,imgx,imgy); } else{ dc.fillRectangle(border,border,width-(border<<1),height-(border<<1)); } drawFrame(dc,0,0,width,height); return 1; } gogglesmm-0.12.7/src/gmdefs.h0000644000175000001440000001057511667311522014526 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMDB_H #define GMDB_H #include "gmconfig.h" #include #include #include #include #include #include #define FOXVERSION ((FOX_LEVEL) + (FOX_MINOR*1000) + (FOX_MAJOR*100000)) #define FXVERSION(major,minor,release) ((release)+(minor*1000)+(major*100000)) #define SQVERSION(major,minor,release) ((release)+(minor*1000)+(major*1000000)) #include "fxext.h" #if FOXVERSION < FXVERSION(1,7,0) #define TIME_NSEC(ns) ((FXuint)(ns/1000000LL)) #define TIME_MSEC(ms) (ms) #define TIME_SEC(s) (1000*s) #define TIME_MIN(m) TIME_SEC(60*m) #define TIME_HOUR(h) TIME_MIN(60*h) #else #define TIME_NSEC(ns) (ns) #define TIME_SEC(s) (1000000000LL*s) #define TIME_MSEC(ms) (1000000LL*ms) #define TIME_MIN(m) TIME_SEC(60*m) #define TIME_HOUR(h) TIME_MIN(60*h) #endif #if FOXVERSION >= FXVERSION(1,7,12) #define GMStringVal(str) FXString::value(str) #define GMStringFormat FXString::value #define GMFloatVal(str) str.toFloat() #define GMIntVal(str) (str).toInt() #else #define GMStringVal(str) FXStringVal(str) #define GMStringFormat FXStringFormat #define GMFloatVal(str) FXFloatVal(str) #define GMIntVal(str) FXIntVal(str) #endif #if FOXVERSION >= FXVERSION(1,7,0) #include #endif #include "GMURL.h" #include "GMAutoPtr.h" #if FOXVERSION < FXVERSION(1,7,0) #include "GMMessageChannel.h" #endif #ifdef DEBUG namespace FX { extern FXlong fxgetticks(); } #define GM_DEBUG_PRINT(format, args...) fxmessage (format , ##args) #else #define GM_DEBUG_PRINT(arguments, args...) ((void)0) #endif #define UTF8_COPYRIGHT_SIGN "\xc2\xa9" #define UTF8_ELLIPSIS "…" #include "GMTag.h" typedef sqlite3 GMDatabaseEngine; typedef sqlite3_stmt GMDatabaseStatement; typedef FXArray FXStringList; typedef FXArray FXIntList; typedef FXArray FXLongList; typedef FXAutoPtr FXCursorPtr; typedef FXAutoPtr FXIconPtr; typedef FXAutoPtr FXImagePtr; typedef FXAutoPtr FXMenuPtr; typedef FXAutoPtr FXFontPtr; typedef FXAutoPtr FXPopupPtr; enum { REPEAT_OFF = 0, REPEAT_TRACK, REPEAT_ALL, }; enum { SOURCE_UNKNOWN = -1, SOURCE_INVALID = -1, SOURCE_DATABASE, SOURCE_DATABASE_PLAYLIST, SOURCE_INTERNET_RADIO, SOURCE_ALBUM, SOURCE_ARTIST, SOURCE_AUDIOCD, }; enum { HEADER_DEFAULT=0, HEADER_SHUFFLE=1, HEADER_BROWSE, HEADER_QUEUE, HEADER_TRACK, HEADER_TITLE, HEADER_ALBUM, HEADER_ARTIST, HEADER_TIME, HEADER_GENRE, HEADER_BITRATE, HEADER_RATING, HEADER_YEAR, HEADER_DISC, HEADER_ALBUM_ARTIST, HEADER_NONE }; struct GMStream{ FXString url; FXString description; FXString genre; FXint bitrate; }; class GMTrackItem; extern const FXchar * fxtr(const FXchar *) __attribute__ ((format_arg(1))); #define notr(x) x #define fxtrformat(x) fxtr(x) #define INVALID_TRACK -1 #include "GMQuery.h" #include "GMDatabase.h" #include "GMPreferences.h" #include "gmutils.h" #include #endif gogglesmm-0.12.7/src/ap_buffer.cpp0000644000175000001440000000641611667274231015551 0ustar sxjusers#include "gmdefs.h" #include "ap_buffer.h" #define ROUNDVAL 16 #define ROUNDUP(n) (((n)+ROUNDVAL-1)&-ROUNDVAL) namespace ap { MemoryBuffer::MemoryBuffer(FXival cap) : buffer(NULL), buffersize(0), rdptr(NULL), wrptr(NULL) { reserve(cap); } MemoryBuffer::MemoryBuffer(const MemoryBuffer & other) : buffer(NULL), buffersize(0), rdptr(NULL), wrptr(NULL) { reserve(other.capacity()); append(other.data(),other.size()); } MemoryBuffer::~MemoryBuffer() { freeElms(buffer); buffersize=0; wrptr=rdptr=NULL; } // Assignment operator MemoryBuffer& MemoryBuffer::operator=(const MemoryBuffer& other) { clear(); reserve(other.capacity()); append(other.data(),other.size()); return *this; } // Append operator MemoryBuffer& MemoryBuffer::operator+=(const MemoryBuffer& other) { reserve(other.capacity()); append(other.data(),other.size()); return *this; } void MemoryBuffer::adopt(MemoryBuffer & other) { // Take over buffer=other.buffer; buffersize=other.buffersize; rdptr=other.rdptr; wrptr=other.wrptr; // Reset Other other.buffer=other.rdptr=other.wrptr=NULL; other.buffersize=0; } // Clear void MemoryBuffer::clear() { wrptr=rdptr=buffer; } // Clear and reset void MemoryBuffer::reset(FXival nbytes) { clear(); if (buffersize!=nbytes) { buffersize=nbytes; resizeElms(buffer,buffersize); wrptr=rdptr=buffer; } } // Make room for needed bytes void MemoryBuffer::reserve(FXival needed) { if (needed>0) { if (buffer) { FXival avail = space(); /// Check if we can move back rdptr/wrptr if (availbuffer) { if (wrptr>rdptr) { memmove(buffer,rdptr,wrptr-rdptr); wrptr-=(rdptr-buffer); rdptr = buffer; avail = space(); } else { wrptr=rdptr=buffer; avail=buffersize; } } } /// Still not enough space, resize buffer if (avail=1); reserve(nbytes); while(nbytes--) *wrptr++=c; } FXival MemoryBuffer::read(void * b, FXival nbytes) { //FXASSERT(nbytessend(msg); } } void GMSettingsDaemon::ReleaseMediaPlayerKeys(const FXchar * pl) { DBusMessage * msg = method("ReleaseMediaPlayerKeys"); if (msg) { dbus_message_append_args(msg,DBUS_TYPE_STRING,&pl,DBUS_TYPE_INVALID); player.clear(); bus->send(msg); } } long GMSettingsDaemon::onSignal(FXObject*,FXSelector,void*ptr){ DBusMessage * msg = reinterpret_cast(ptr); if (dbus_message_is_signal(msg,GNOME_SETTINGS_DAEMON_INTERFACE,"MediaPlayerKeyPressed")){ const FXchar * pl=NULL; const FXchar * cmd=NULL; if (dbus_message_get_args(msg,NULL,DBUS_TYPE_STRING,&pl,DBUS_TYPE_STRING,&cmd,DBUS_TYPE_INVALID)) { if (compare(pl,player)==0 && target && cmd) { target->handle(this,FXSEL(SEL_KEYPRESS,message),(void*)cmd); } } return 1; } return 0; } gogglesmm-0.12.7/src/GMSearch.h0000644000175000001440000000666511525430601014710 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMSEARCHDIALOG_H #define GMSEARCHDIALOG_H class GMTrackDatabase; class GMThread; class GMAnimImage; class GMThreadDialog : public FXDialogBox { FXDECLARE(GMThreadDialog) protected: FXImage * animation_image; FXint animation_size; GMThread * thread; GMThreadDialog(); private: GMThreadDialog(const GMThreadDialog&); GMThreadDialog& operator=(const GMThreadDialog&); public: enum { ID_THREAD_DONE = FXDialogBox::ID_LAST, ID_THREAD_ERROR, ID_THREAD_PROGRESS }; public: long onCmdCancel(FXObject*,FXSelector,void*); long onThreadDone(FXObject*,FXSelector,void*); long onThreadError(FXObject*,FXSelector,void*); public: GMThreadDialog(FXWindow * owner); virtual FXuint execute(FXuint placement=PLACEMENT_CURSOR); virtual ~GMThreadDialog(); }; class GMImportDatabase : public GMThreadDialog { FXDECLARE(GMImportDatabase) protected: FXTextField * text_file; FXTextField * text_dir; FXTextField * text_count; protected: GMImportDatabase(); private: GMImportDatabase(const GMImportDatabase&); GMImportDatabase& operator=(const GMImportDatabase&); public: long onThreadProgress(FXObject*,FXSelector,void*); public: GMImportDatabase(FXWindow * owner,const FXStringList & files,const GMImportOptions & pref,FXint playlist,FXFont * font); virtual ~GMImportDatabase(); }; class GMSyncDatabase : public GMThreadDialog { FXDECLARE(GMSyncDatabase) protected: FXSwitcher * contentswitcher; FXLabel * label_title; FXLabel * label_sync; FXProgressBar * progressbar; FXTextField * text_file; FXTextField * text_dir; FXTextField * text_count; protected: GMSyncDatabase(); private: GMSyncDatabase(const GMSyncDatabase&); GMSyncDatabase& operator=(const GMSyncDatabase&); public: long onThreadProgress(FXObject*,FXSelector,void*); public: GMSyncDatabase(FXWindow * owner,const FXStringList & files,const GMImportOptions & io,const GMSyncOptions & so,FXint playlist,FXbool tags,FXFont * font); virtual ~GMSyncDatabase(); }; #endif gogglesmm-0.12.7/src/GMTrackView.cpp0000644000175000001440000022056412022221704015724 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include #include "GMApp.h" #include "GMList.h" #include "GMTrackList.h" #include "GMTrackView.h" #include "GMWindow.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMIconTheme.h" #include "GMClipboard.h" #include "GMSourceView.h" #include "GMColumnDialog.h" #define HIDEBROWSER (FX4Splitter::ExpandBottomLeft) #define SHOWBROWSER (FX4Splitter::ExpandTopLeft|FX4Splitter::ExpandTopRight|FX4Splitter::ExpandBottomLeft) static inline FXbool begins_with_keyword(const FXString & t){ for (FXint i=0;igetPreferences().gui_sort_keywords.no();i++){ if (comparecase(t,GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i],GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i].length())==0) return TRUE; } return FALSE; } static FXint album_selectionchanged=-1; static FXint artist_selectionchanged=-1; static FXint genre_selectionchanged=-1; FXbool GMTrackView::reverse_artist=false; FXbool GMTrackView::reverse_album=false; FXbool GMTrackView::album_by_year=true; class GMStaticMenuCheck : public GMMenuCheck { FXDECLARE(GMStaticMenuCheck) protected: GMStaticMenuCheck(); private: GMStaticMenuCheck(const GMStaticMenuCheck&); GMStaticMenuCheck &operator=(const GMStaticMenuCheck&); public: long onButtonRelease(FXObject*,FXSelector,void*); long onKeyRelease(FXObject*,FXSelector,void*); public: GMStaticMenuCheck(FXComposite* p,const FXString& text,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0); virtual ~GMStaticMenuCheck(); }; FXDEFMAP(GMStaticMenuCheck) GMStaticMenuCheckMap[]={ FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,GMStaticMenuCheck::onButtonRelease), FXMAPFUNC(SEL_KEYRELEASE,0,GMStaticMenuCheck::onKeyRelease) }; FXIMPLEMENT(GMStaticMenuCheck,GMMenuCheck,GMStaticMenuCheckMap,ARRAYNUMBER(GMStaticMenuCheckMap)) GMStaticMenuCheck::GMStaticMenuCheck(){ } GMStaticMenuCheck::GMStaticMenuCheck(FXComposite* p,const FXString& text,FXObject* tgt,FXSelector sel,FXuint opts) : GMMenuCheck(p,text,tgt,sel,opts) { } GMStaticMenuCheck::~GMStaticMenuCheck(){ } // Released button long GMStaticMenuCheck::onButtonRelease(FXObject*,FXSelector,void*){ FXbool active=isActive(); if(!isEnabled()) return 0; if(active){ setCheck(!check); if(target){ target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)check); } } return 1; } // Keyboard release long GMStaticMenuCheck::onKeyRelease(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; if(isEnabled() && (flags&FLAG_PRESSED)){ FXTRACE((200,"%s::onKeyRelease %p keysym=0x%04x state=%04x\n",getClassName(),this,event->code,event->state)); if(event->code==KEY_space || event->code==KEY_KP_Space || event->code==KEY_Return || event->code==KEY_KP_Enter){ flags&=~FLAG_PRESSED; setCheck(!check); if(target) target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXuval)check); return 1; } } return 0; } FXDEFMAP(GMTrackView) GMTrackViewMap[]={ FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_TOGGLE_BROWSER,GMTrackView::onUpdToggleBrowser), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_TOGGLE_GENRES,GMTrackView::onUpdToggleGenres), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_TOGGLE_FILTER,GMTrackView::onUpdToggleFilter), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_COPY,GMTrackView::onUpdCopy), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_PASTE,GMTrackView::onUpdPaste), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_SHOW_CURRENT,GMTrackView::onUpdShowCurrent), FXMAPFUNCS(SEL_UPDATE,GMTrackView::ID_FILTER_TRACK,GMTrackView::ID_FILTER_LAST,GMTrackView::onUpdFilterMask), FXMAPFUNCS(SEL_COMMAND,GMTrackView::ID_FILTER_TRACK,GMTrackView::ID_FILTER_LAST,GMTrackView::onCmdFilterMask), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_ARTIST_LIST_HEADER,GMTrackView::onCmdSortArtistList), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_ALBUM_LIST_HEADER,GMTrackView::onCmdSortAlbumList), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_GENRE_LIST_HEADER,GMTrackView::onCmdSortGenreList), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_TOGGLE_BROWSER,GMTrackView::onCmdToggleBrowser), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_TOGGLE_GENRES,GMTrackView::onCmdToggleGenres), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_TOGGLE_FILTER,GMTrackView::onCmdToggleFilter), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_CLOSE_FILTER,GMTrackView::onCmdToggleFilter), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_COPY,GMTrackView::onCmdCopy), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_PASTE,GMTrackView::onCmdPaste), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_SHOW_CURRENT,GMTrackView::onCmdShowCurrent), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_FILTER,GMTrackView::onCmdFilter), FXMAPFUNC(SEL_CHANGED,GMTrackView::ID_FILTER,GMTrackView::onCmdFilter), FXMAPFUNC(SEL_TIMEOUT,GMTrackView::ID_FILTER,GMTrackView::onCmdFilter), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_FILTER_MODE,GMTrackView::onCmdFilter), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_GENRE_LIST,GMTrackView::onCmdGenreSelected), FXMAPFUNC(SEL_SELECTED,GMTrackView::ID_GENRE_LIST,GMTrackView::onCmdGenreSelected), FXMAPFUNC(SEL_DESELECTED,GMTrackView::ID_GENRE_LIST,GMTrackView::onCmdGenreSelected), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdArtistSelected), FXMAPFUNC(SEL_SELECTED,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdArtistSelected), FXMAPFUNC(SEL_DESELECTED,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdArtistSelected), FXMAPFUNC(SEL_DOUBLECLICKED,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdArtistSelected), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdAlbumSelected), FXMAPFUNC(SEL_SELECTED,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdAlbumSelected), FXMAPFUNC(SEL_DESELECTED,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdAlbumSelected), FXMAPFUNC(SEL_DOUBLECLICKED,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdAlbumSelected), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_GENRE_LIST,GMTrackView::onGenreContextMenu), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_ARTIST_LIST,GMTrackView::onArtistContextMenu), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_ALBUM_LIST,GMTrackView::onAlbumContextMenu), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_TRACK_LIST,GMTrackView::onTrackContextMenu), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_TRACK_LIST_HEADER,GMTrackView::onTrackHeaderContextMenu), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMTrackView::ID_ALBUM_LIST_HEADER,GMTrackView::onAlbumHeaderContextMenu), FXMAPFUNC(SEL_KEYPRESS,GMTrackView::ID_GENRE_LIST,GMTrackView::onCmdGenreKeyPress), FXMAPFUNC(SEL_KEYPRESS,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdArtistKeyPress), FXMAPFUNC(SEL_KEYPRESS,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdAlbumKeyPress), FXMAPFUNC(SEL_KEYPRESS,GMTrackView::ID_TRACK_LIST,GMTrackView::onCmdTrackKeyPress), FXMAPFUNC(SEL_DOUBLECLICKED,GMTrackView::ID_TRACK_LIST,GMTrackView::onCmdPlayTrack), FXMAPFUNC(SEL_BEGINDRAG,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdBeginDrag), FXMAPFUNC(SEL_BEGINDRAG,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdBeginDrag), FXMAPFUNC(SEL_BEGINDRAG,GMTrackView::ID_TRACK_LIST,GMTrackView::onCmdBeginDrag), FXMAPFUNC(SEL_DRAGGED,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdDragged), FXMAPFUNC(SEL_DRAGGED,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdDragged), FXMAPFUNC(SEL_DRAGGED,GMTrackView::ID_TRACK_LIST,GMTrackView::onCmdDragged), FXMAPFUNC(SEL_ENDDRAG,GMTrackView::ID_ARTIST_LIST,GMTrackView::onCmdEndDrag), FXMAPFUNC(SEL_ENDDRAG,GMTrackView::ID_ALBUM_LIST,GMTrackView::onCmdEndDrag), FXMAPFUNC(SEL_ENDDRAG,GMTrackView::ID_TRACK_LIST,GMTrackView::onCmdEndDrag), FXMAPFUNC(SEL_DND_ENTER,GMTrackView::ID_TRACK_LIST,GMTrackView::onDndTrackEnter), FXMAPFUNC(SEL_DND_LEAVE,GMTrackView::ID_TRACK_LIST,GMTrackView::onDndTrackLeave), FXMAPFUNC(SEL_DND_MOTION,GMTrackView::ID_TRACK_LIST,GMTrackView::onDndTrackMotion), FXMAPFUNC(SEL_DND_DROP,GMTrackView::ID_TRACK_LIST,GMTrackView::onDndTrackDrop), FXMAPFUNC(SEL_DND_MOTION,GMTrackView::ID_GENRE_LIST,GMTrackView::onDndMotion), FXMAPFUNC(SEL_DND_MOTION,GMTrackView::ID_ARTIST_LIST,GMTrackView::onDndMotion), FXMAPFUNC(SEL_DND_MOTION,GMTrackView::ID_ALBUM_LIST,GMTrackView::onDndMotion), FXMAPFUNC(SEL_DND_DROP,GMTrackView::ID_GENRE_LIST,GMTrackView::onDndDrop), FXMAPFUNC(SEL_DND_DROP,GMTrackView::ID_ARTIST_LIST,GMTrackView::onDndDrop), FXMAPFUNC(SEL_DND_DROP,GMTrackView::ID_ALBUM_LIST,GMTrackView::onDndDrop), FXMAPFUNC(SEL_DND_REQUEST,GMTrackView::ID_ARTIST_LIST,GMTrackView::onDndRequest), FXMAPFUNC(SEL_DND_REQUEST,GMTrackView::ID_ALBUM_LIST,GMTrackView::onDndRequest), FXMAPFUNC(SEL_DND_REQUEST,GMTrackView::ID_TRACK_LIST,GMTrackView::onDndRequest), FXMAPFUNCS(SEL_COMMAND,GMTrackView::ID_COLUMN_FIRST,GMTrackView::ID_COLUMN_LAST,GMTrackView::onCmdShowColumn), FXMAPFUNCS(SEL_UPDATE,GMTrackView::ID_COLUMN_FIRST,GMTrackView::ID_COLUMN_LAST,GMTrackView::onUpdShowColumn), FXMAPFUNCS(SEL_COMMAND,GMTrackView::ID_SORT_FIRST,GMTrackView::ID_SORT_LAST,GMTrackView::onCmdSort), FXMAPFUNCS(SEL_UPDATE,GMTrackView::ID_SORT_FIRST,GMTrackView::ID_SORT_LAST,GMTrackView::onUpdSort), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_SORT_REVERSE,GMTrackView::onUpdSortReverse), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_SORT_BROWSE,GMTrackView::onUpdSortBrowse), FXMAPFUNC(SEL_UPDATE,GMTrackView::ID_SORT_SHUFFLE,GMTrackView::onUpdSortShuffle), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_SORT_SHUFFLE,GMTrackView::onCmdSortShuffle), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_SORT_BROWSE,GMTrackView::onCmdSortBrowse), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_SORT_DEFAULT,GMTrackView::onCmdSortDefault), FXMAPFUNC(SEL_CHORE,GMTrackView::ID_LOAD_ALBUM_ICONS,GMTrackView::onCmdLoadAlbumIcons), FXMAPFUNC(SEL_COMMAND,GMTrackView::ID_CONFIGURE_COLUMNS,GMTrackView::onCmdConfigureColumns), }; FXIMPLEMENT(GMTrackView,FXPacker,GMTrackViewMap,ARRAYNUMBER(GMTrackViewMap)) GMTrackView::GMTrackView() { source = NULL; } GMTrackView::GMTrackView(FXComposite* p) : FXPacker(p,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0) , source(NULL) { GMScrollFrame * sunkenframe; #if FOXVERSION < FXVERSION(1,7,0) shuffle_seed = (FXuint)FXSystem::now(); #else shuffle_seed = (FXuint)FXThread::time(); #endif filtermask=FILTER_DEFAULT; updateFont(); filtermenu = new GMMenuPane(getShell()); new GMStaticMenuCheck(filtermenu,tr("Title"),this,ID_FILTER_TRACK); new GMStaticMenuCheck(filtermenu,tr("Artist"),this,ID_FILTER_ARTIST); new GMStaticMenuCheck(filtermenu,tr("Album"),this,ID_FILTER_ALBUM); new GMStaticMenuCheck(filtermenu,tr("Genre"),this,ID_FILTER_GENRE); filterframe = new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|PACK_UNIFORM_HEIGHT,0,0,0,0,0,0,0,0); new GMButton(filterframe,tr("\tClose Filter\tClose Filter"),GMIconTheme::instance()->icon_close,this,ID_CLOSE_FILTER,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_RIGHT); new FXMenuButton(filterframe,tr("&Find"),GMIconTheme::instance()->icon_find,filtermenu,MENUBUTTON_NOARROWS|FRAME_RAISED|MENUBUTTON_TOOLBAR|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y); filterfield = new GMTextField(filterframe,20,this,ID_FILTER,LAYOUT_FILL_X|FRAME_LINE); browsersplit = new FX4Splitter(this,LAYOUT_FILL_X|LAYOUT_FILL_Y|FOURSPLITTER_TRACKING); genresplit = new FX4Splitter(browsersplit,FOURSPLITTER_TRACKING); genrelistframe = new GMScrollFrame(genresplit); genrelistheader = new GMHeaderButton(genrelistframe,tr("Genres\tPress to change sorting order\tPress to change sorting order"),NULL,this,GMTrackView::ID_GENRE_LIST_HEADER,LAYOUT_FILL_X|FRAME_RAISED|JUSTIFY_LEFT); genrelist = new GMList(genrelistframe,this,ID_GENRE_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LIST_EXTENDEDSELECT); sunkenframe = new GMScrollFrame(genresplit); artistlistheader = new GMHeaderButton(sunkenframe,tr("Artists\tPress to change sorting order\tPress to change sorting order"),NULL,this,GMTrackView::ID_ARTIST_LIST_HEADER,LAYOUT_FILL_X|FRAME_RAISED|JUSTIFY_LEFT); artistlist = new GMList(sunkenframe,this,ID_ARTIST_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LIST_EXTENDEDSELECT); sunkenframe = new GMScrollFrame(browsersplit); albumlistheader = new GMHeaderButton(sunkenframe,tr("Albums\tPress to change sorting order\tPress to change sorting order"),NULL,this,GMTrackView::ID_ALBUM_LIST_HEADER,LAYOUT_FILL_X|FRAME_RAISED|JUSTIFY_LEFT); albumlist = new GMList(sunkenframe,this,ID_ALBUM_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LIST_EXTENDEDSELECT); sunkenframe = new GMScrollFrame(browsersplit); tracklist = new GMTrackList(sunkenframe,this,ID_TRACK_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|TRACKLIST_EXTENDEDSELECT); columnmenu = new GMMenuPane(getShell()); for (FXint i=ID_COLUMN_FIRST;igetDefaultCursor(DEF_ARROW_CURSOR)); gm_set_window_cursor(columnmenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); gm_set_window_cursor(filtermenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); genrelist->setNumVisible(9); artistlist->setNumVisible(9); albumlist->setNumVisible(9); genrelist->setThickFont(font_listhead); artistlist->setThickFont(font_listhead); albumlist->setThickFont(font_listhead); tracklist->setActiveFont(font_listhead); genrelist->dropEnable(); artistlist->dropEnable(); albumlist->dropEnable(); tracklist->dropEnable(); genrelist->setSortFunc(genre_list_sort); artistlist->setSortFunc(artist_list_sort); albumlist->setSortFunc(album_list_sort); genrelistheader->setArrowState(ARROW_DOWN); artistlistheader->setArrowState(ARROW_DOWN); albumlistheader->setArrowState(ARROW_DOWN); browsersplit->setBarSize(7); genresplit->setBarSize(7); getShell()->getAccelTable()->addAccel(parseAccel("Ctrl-N"),this,FXSEL(SEL_COMMAND,ID_SORT_DEFAULT)); updateColors(); } GMTrackView::~GMTrackView(){ getApp()->removeChore(this,ID_LOAD_ALBUM_ICONS); getApp()->removeTimeout(this,ID_FILTER); } void GMTrackView::updateFont() { #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getApp()->getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getApp()->getNormalFont()->getFontDesc(); #endif fontdescription.slant = FXFont::Italic; fontdescription.weight = FXFont::Bold; fontdescription.size -= 10; if (font_listhead) { font_listhead->destroy(); font_listhead->setFontDesc(fontdescription); font_listhead->create(); } else { font_listhead = new FXFont(getApp(),fontdescription); font_listhead->create(); } } void GMTrackView::updateColors(){ tracklist->setRowColor(GMPlayerManager::instance()->getPreferences().gui_row_color); tracklist->setActiveColor(GMPlayerManager::instance()->getPreferences().gui_play_color); tracklist->setActiveTextColor(GMPlayerManager::instance()->getPreferences().gui_playtext_color); genrelist->setRowColor(GMPlayerManager::instance()->getPreferences().gui_row_color); artistlist->setRowColor(GMPlayerManager::instance()->getPreferences().gui_row_color); albumlist->setRowColor(GMPlayerManager::instance()->getPreferences().gui_row_color); } void GMTrackView::updateIcons(){ FXint i=0; FXIcon * icon_genre = NULL; FXIcon * icon_artist = NULL; FXIcon * icon_album = NULL; if (GMPlayerManager::instance()->getPreferences().gui_show_browser_icons) { icon_genre = GMIconTheme::instance()->icon_genre; icon_artist = GMIconTheme::instance()->icon_artist; icon_album = GMIconTheme::instance()->icon_album; } for (i=0;igetNumItems();i++){ genrelist->setItemIcon(i,icon_genre); } for (i=0;igetNumItems();i++){ artistlist->setItemIcon(i,icon_artist); } for (i=0;igetNumItems();i++){ albumlist->setItemIcon(i,icon_album); } } void GMTrackView::clear() { genrelist->clearItems(); artistlist->clearItems(); albumlist->clearItems(); tracklist->clearItems(); tracklist->setActiveItem(-1); } void GMTrackView::mark(FXint item,FXbool show/*=true*/) { if (source && item>=0){ source->markCurrent(tracklist,item); if (show) tracklist->setCurrentItem(item); } if (show) tracklist->setActiveItem(item); } void GMTrackView::showCurrent() { FXASSERT(source); FXASSERT(GMPlayerManager::instance()->getSource()); source->findCurrent(tracklist,GMPlayerManager::instance()->getSource()); } FXint GMTrackView::getCurrent() const{ /* // Any Items? if (tracklist->getNumItems()==0) return -1; // First Selected for (FXint i=0;igetNumItems();i++){ if (tracklist->isItemSelected(i)) return i; } /// First Item return 0; */ return tracklist->getCurrentItem(); } //generates a psuedo-random integer between min and max extern int randint(int min, int max,unsigned int * random_seed); FXint GMTrackView::getNext(FXbool wrap){ if (tracklist->getNumItems()==0) { return -1; } else if (tracklist->getNumItems()>2 && GMPlayerManager::instance()->getPreferences().play_shuffle) { if (tracklist->getActiveItem()>=0){ for (FXint i=0,track=0;i<10;i++) { track = randint(0,tracklist->getNumItems()-1,&shuffle_seed); if (track!=tracklist->getActiveItem()) return track; } } return randint(0,tracklist->getNumItems()-1,&shuffle_seed); } else if (tracklist->getActiveItem()==tracklist->getNumItems()-1){ if (GMPlayerManager::instance()->getPreferences().play_repeat==REPEAT_ALL || wrap) return 0; else { if (tracklist->getCurrentItem()==tracklist->getNumItems()-1){ tracklist->setCurrentItem(0); } return -1; } } return tracklist->getActiveItem()+1; } FXint GMTrackView::getPrevious(){ if (tracklist->getNumItems()==0) { return -1; } else if (tracklist->getNumItems()>2 && GMPlayerManager::instance()->getPreferences().play_shuffle) { if (tracklist->getActiveItem()>=0){ for (FXint i=0,track=0;i<10;i++) { track = randint(0,tracklist->getNumItems()-1,&shuffle_seed); if (track!=tracklist->getActiveItem()) return track; } } return randint(0,tracklist->getNumItems()-1,&shuffle_seed); } else if (tracklist->getActiveItem()==0) { return tracklist->getNumItems()-1; } else { return tracklist->getActiveItem()-1; } } FXString GMTrackView::getTrackFilename(FXint item) const { FXint track = tracklist->getItemId(item); if (source && track!=-1 ) return source->getTrackFilename(track); return FXString::null; } void GMTrackView::getTracks(FXIntList & tracks) const{ for (FXint i=0;igetNumItems();i++){ tracks.append(tracklist->getItemId(i)); } } static int compareindex(const void *a,const void *b){ register FXint * aa = (FXint*)a; register FXint * bb = (FXint*)b; if ((*aa) > (*bb)) return 1; else if ((*aa) < (*bb)) return -1; return 0; } void GMTrackView::getSelectedGenres(FXIntList & genres) const{ if (genrelist->getNumItems()==1) { if (genrelist->isItemSelected(0) && ((FXint)(FXival)genrelist->getItemData(0))!=-1) genres.append((FXint)(FXival)genrelist->getItemData(0)); } else { for (FXint i=1;igetNumItems();i++){ if (genrelist->isItemSelected(i)) { genres.append((FXint)(FXival)genrelist->getItemData(i)); } } } qsort(genres.data(),genres.no(),sizeof(FXint),compareindex); } void GMTrackView::getSelectedArtists(FXIntList & artists) const{ if (artistlist->getNumItems()==1) { if (artistlist->isItemSelected(0) && ((FXint)(FXival)artistlist->getItemData(0))!=-1) artists.append((FXint)(FXival)artistlist->getItemData(0)); } else { for (FXint i=1;igetNumItems();i++){ if (artistlist->isItemSelected(i)) { artists.append((FXint)(FXival)artistlist->getItemData(i)); } } } qsort(artists.data(),artists.no(),sizeof(FXint),compareindex); } void GMTrackView::getSelectedAlbums(FXIntList & albums) const{ register FXint i=0; if (albumlist->getNumItems()) { if (albumlist->getItemData(0)==(void*)(FXival)-1) { if (albumlist->isItemSelected(0)){ for (i=1;igetNumItems();i++){ albums.append((FXint)(FXival)albumlist->getItemData(i)); albums.append(((GMAlbumListItem*)albumlist->getItem(i))->albums); } } else { for (i=1;igetNumItems();i++){ if (albumlist->isItemSelected(i)) { albums.append((FXint)(FXival)albumlist->getItemData(i)); albums.append(((GMAlbumListItem*)albumlist->getItem(i))->albums); } } } } else { for (i=0;igetNumItems();i++){ if (albumlist->isItemSelected(i)) { albums.append((FXint)(FXival)albumlist->getItemData(i)); albums.append(((GMAlbumListItem*)albumlist->getItem(i))->albums); } } } } qsort(albums.data(),albums.no(),sizeof(FXint),compareindex); } void GMTrackView::getSelectedTracks(FXIntList & tracks) const{ for (FXint i=0;igetNumItems();i++){ if (tracklist->isItemSelected(i)) { tracks.append(tracklist->getItemId(i)); } } } FXint GMTrackView::numTrackSelected() const { FXint num=0; for (FXint i=0;igetNumItems();i++){ if (tracklist->isItemSelected(i)) num++; } return num; } FXbool GMTrackView::trackSelected() const { for (FXint i=0;igetNumItems();i++){ if (tracklist->isItemSelected(i)) return true; } return false; } FXbool GMTrackView::hasTracks() const { return tracklist->getNumItems()>0; } void GMTrackView::selectGenreItem(FXint item) { genrelist->killSelection(true); genrelist->selectItem(item,true); genrelist->setCurrentItem(item,true); handle(this,FXSEL(SEL_COMMAND,ID_GENRE_LIST),(void*)(FXival)item); } void GMTrackView::selectArtistItem(FXint item) { artistlist->killSelection(true); artistlist->selectItem(item,true); artistlist->setCurrentItem(item,true); handle(this,FXSEL(SEL_COMMAND,ID_ARTIST_LIST),(void*)(FXival)item); } void GMTrackView::selectAlbumItem(FXint item) { albumlist->killSelection(true); albumlist->selectItem(item,true); albumlist->setCurrentItem(item,true); handle(this,FXSEL(SEL_COMMAND,ID_ALBUM_LIST),(void*)(FXival)item); } void GMTrackView::selectTrackItem(FXint item) { tracklist->killSelection(); tracklist->selectItem(item); tracklist->setCurrentItem(item); } void GMTrackView::setSource(GMSource * src) { if (source!=src) { if (source) { saveSettings(source->settingKey()); if (browsersplit->getExpanded()==SHOWBROWSER){ saveSelection(genrelist,"genre-list-selection",source->settingKey()); saveSelection(artistlist,"artist-list-selection",source->settingKey()); saveSelection(albumlist,"album-list-selection",source->settingKey()); } } source=src; if (source) { columns.clear(); source->configure(columns); loadSettings(source->settingKey()); clear(); if (browsersplit->getExpanded()==SHOWBROWSER) { listGenres(); initSelection(genrelist,"genre-list-selection",source->settingKey()); listArtists(); initSelection(artistlist,"artist-list-selection",source->settingKey()); listAlbums(); initSelection(albumlist,"album-list-selection",source->settingKey()); listTracks(); } else { listTracks(); } tracklist->setPosition(tracklist_posx,tracklist_posy); } } } void GMTrackView::saveSelection(GMList * list,const char * key,const FXString & section) const{ FXString value; for (FXint i=0;igetNumItems();i++){ if (list->isItemSelected(i)) value+=GMStringVal(i)+";"; } getApp()->reg().writeStringEntry(section.text(),key,value.text()); } void GMTrackView::initSelection(GMList * list,const FXchar * key,const FXString & section){ FXint i=0,x=0,nselected=0; FXString part; FXString view = getApp()->reg().readStringEntry(section.text(),key,""); if (!view.empty()){ list->killSelection(false); part=view.section(';',i); while(!part.empty()){ #if FOXVERSION >= FXVERSION(1,7,12) x = part.toInt(); #else x = FXIntVal(part); #endif if (x>=0 && xgetNumItems()){ nselected++; list->selectItem(x); if (i==0) list->makeItemVisible(x); } part=view.section(';',++i); } if (nselected==0 && list->getNumItems()){ list->selectItem(0); } } } void GMTrackView::init(GMSource * src) { FXASSERT(source==NULL); FXASSERT(src); source=src; columns.clear(); source->configure(columns); loadSettings(source->settingKey()); clear(); if (source) { if (browsersplit->getExpanded()==SHOWBROWSER) { listGenres(); initSelection(genrelist,"genre-list-selection",source->settingKey()); listArtists(); initSelection(artistlist,"artist-list-selection",source->settingKey()); listAlbums(); initSelection(albumlist,"album-list-selection",source->settingKey()); listTracks(); } else { listTracks(); } FXint active = getApp()->reg().readIntEntry("window","track-list-current",-1); if (active>=0 && activegetNumItems()) { tracklist->setCurrentItem(active); tracklist->selectItem(active); } tracklist->setPosition(tracklist_posx,tracklist_posy); } } void GMTrackView::saveView() const { if (source) saveSettings(source->settingKey()); if (browsersplit->getExpanded()==SHOWBROWSER){ saveSelection(genrelist,"genre-list-selection",source->settingKey()); saveSelection(artistlist,"artist-list-selection",source->settingKey()); saveSelection(albumlist,"album-list-selection",source->settingKey()); } getApp()->reg().writeIntEntry("window","track-list-current",tracklist->getActiveItem()); } void GMTrackView::refresh() { clear(); if (source) { if (browsersplit->getExpanded()==SHOWBROWSER) { listGenres(); listArtists(); listAlbums(); listTracks(); } else { listTracks(); } } } void GMTrackView::resort() { sortGenres(); sortArtists(); sortAlbums(); sortTracks(); } FXbool GMTrackView::listGenres() { if (source) { FXIcon * icon = NULL; if (GMPlayerManager::instance()->getPreferences().gui_show_browser_icons) icon = GMIconTheme::instance()->icon_genre; if (!source->listGenres(genrelist,icon)) return false; genrelist->sortItems(); if (genrelist->getNumItems()>1) genrelist->prependItem(GMStringFormat(fxtrformat("All %d Genres"),genrelist->getNumItems()),icon,(void*)(FXival)-1); else genrelist->prependItem(tr("All Genres"),icon,(void*)(FXival)-1); genrelist->setCurrentItem(0,false); genrelist->selectItem(0,false); } return true; } FXbool GMTrackView::listArtists(){ if (source) { FXIcon * icon = NULL; if (GMPlayerManager::instance()->getPreferences().gui_show_browser_icons) icon = GMIconTheme::instance()->icon_artist; FXIntList genreselection; getSelectedGenres(genreselection); if (!source->listArtists(artistlist,icon,genreselection)) return false; artistlist->sortItems(); if (artistlist->getNumItems()>1) { artistlist->prependItem(GMStringFormat(fxtrformat("All %d Artists"),artistlist->getNumItems()),icon,(void*)(FXival)-1); } if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) { if (source->findCurrentArtist(artistlist,GMPlayerManager::instance()->getSource())) { return true; } } if (artistlist->getNumItems()){ artistlist->setCurrentItem(0,false); artistlist->selectItem(0,false); } } return true; } FXbool GMTrackView::listAlbums(){ if (source) { FXIcon * icon = NULL; if (GMPlayerManager::instance()->getPreferences().gui_show_browser_icons) { if (GMPlayerManager::instance()->getPreferences().gui_show_albumcovers) icon = GMIconTheme::instance()->icon_nocover; else icon = GMIconTheme::instance()->icon_album; } FXIntList genreselection; FXIntList artistselection; getSelectedGenres(genreselection); getSelectedArtists(artistselection); if (!source->listAlbums(albumlist,icon,artistselection,genreselection)) return false; albumlist->sortItems(); if (albumlist->getNumItems()>1){ albumlist->prependItem(GMStringFormat(fxtrformat("All %d Albums"),albumlist->getNumItems()),icon,(void*)(FXival)-1); } if (albumlist->getNumItems() && GMPlayerManager::instance()->getPreferences().gui_show_albumcovers) getApp()->addChore(this,ID_LOAD_ALBUM_ICONS,(void*)(FXival)0); if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) { if (source->findCurrentAlbum(albumlist,GMPlayerManager::instance()->getSource())) { return true; } } if (albumlist->getNumItems()) { albumlist->setCurrentItem(0,false); albumlist->selectItem(0,false); } } return true; } FXbool GMTrackView::listTracks(){ if (source) { tracklist->setActiveItem(-1); FXIntList genreselection; FXIntList albumselection; if (browsersplit->getExpanded()==SHOWBROWSER){ getSelectedGenres(genreselection); getSelectedAlbums(albumselection); if (albumselection.no()==0) return false; } if (!source->listTracks(tracklist,albumselection,genreselection)) return false; layout(); tracklist->setCurrentItem(-1); if (tracklist->getNumItems()) { sortTracks(); if (tracklist->getCurrentItem()==-1) tracklist->setCurrentItem(0); } /* if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) source->findCurrent(tracklist,GMPlayerManager::instance()->getSource()); */ //fxmessage("getCurrentItem()==%d\n",tracklist->getCurrentItem()); } return true; } void GMTrackView::sortGenres() const{ genrelist->sortItems(); /// Make sure "All" is on top. FXint data=-1; FXint all = genrelist->findItemByData((void*)(FXival)(FXint)data); if (all>0) { genrelist->moveItem(0,all); } } void GMTrackView::sortArtists() const{ artistlist->sortItems(); /// Make sure "All" is on top. FXint data=-1; FXint all = artistlist->findItemByData((void*)(FXival)(FXint)data); if (all>0) { artistlist->moveItem(0,all); } } void GMTrackView::sortAlbums() const { albumlist->sortItems(); /// Make sure "All" is on top. FXint data=-1; FXint all = albumlist->findItemByData((void*)(FXival)(FXint)data); if (all>0) { albumlist->moveItem(0,all); } } void GMTrackView::sortTracks() const{ if (tracklist->getSortMethod()==HEADER_SHUFFLE) source->shuffle(tracklist,sort_seed); else tracklist->sortItems(); if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) source->findCurrent(tracklist,GMPlayerManager::instance()->getSource()); } void GMTrackView::setSortMethod(FXint def,FXbool reverse) { if (def==HEADER_BROWSE) { tracklist->setSortMethod(HEADER_BROWSE); tracklist->setSortFunc(source->getSortBrowse()); } else if (def==HEADER_SHUFFLE) { tracklist->setSortMethod(HEADER_SHUFFLE); tracklist->setSortFunc(NULL); } else { for (FXint i=0;isetSortMethod(columns[i].type); if (reverse) tracklist->setSortFunc(columns[i].descending); else tracklist->setSortFunc(columns[i].ascending); break; } } } } FXbool GMTrackView::getSortReverse() const { for (FXint i=0;igetSortMethod()) { if (columns[i].descending==tracklist->getSortFunc()) return true; break; } } return false; } void GMTrackView::loadSettings(const FXString & key) { FXbool sort_reverse,shown; FXint split; sort_reverse = getApp()->reg().readBoolEntry(key.text(),"genre-list-sort-reverse",false); if (sort_reverse) { genrelist->setSortFunc(genre_list_sort_reverse); genrelistheader->setArrowState(ARROW_UP); } else { genrelist->setSortFunc(genre_list_sort); genrelistheader->setArrowState(ARROW_DOWN); } reverse_artist = getApp()->reg().readBoolEntry(key.text(),"artist-list-sort-reverse",false); if (reverse_artist) { artistlist->setSortFunc(artist_list_sort_reverse); artistlistheader->setArrowState(ARROW_UP); } else { artistlist->setSortFunc(artist_list_sort); artistlistheader->setArrowState(ARROW_DOWN); } album_by_year = getApp()->reg().readBoolEntry(key.text(),"album-list-sort-by-year",false); reverse_album = getApp()->reg().readBoolEntry(key.text(),"album-list-sort-reverse",false); if (reverse_album) { albumlist->setSortFunc(album_list_sort_reverse); albumlistheader->setArrowState(ARROW_UP); } else { albumlist->setSortFunc(album_list_sort); albumlistheader->setArrowState(ARROW_DOWN); } shown = getApp()->reg().readBoolEntry(key.text(),"genre-list",false); if (shown) genrelistframe->show(); else genrelistframe->hide(); shown = getApp()->reg().readBoolEntry(key.text(),"browser",source->defaultBrowse()); if (shown && source->canBrowse()) browsersplit->setExpanded(SHOWBROWSER); else browsersplit->setExpanded(HIDEBROWSER); split = getApp()->reg().readIntEntry(key.text(),"browser-track-split",-1); if (split!=-1) browsersplit->setVSplit(split); split = getApp()->reg().readIntEntry(key.text(),"artist-album-split",-1); if (split!=-1) browsersplit->setHSplit(split); split = getApp()->reg().readIntEntry(key.text(),"genre-artist-split",-1); if (split!=-1) genresplit->setHSplit(split); // split = getApp()->reg().readIntEntry(key.text(),"browser-split",-1); // if (split!=-1) setSplit(0,split); tracklist_posx = getApp()->reg().readIntEntry(key.text(),"track-list-posx",0); tracklist_posy = getApp()->reg().readIntEntry(key.text(),"track-list-posy",0); shown = getApp()->reg().readBoolEntry(key.text(),"filter",true); if (shown && source && source->canFilter()) filterframe->show(); else filterframe->hide(); filterfield->setText(getApp()->reg().readStringEntry(key.text(),"filter-text","")); if (getApp()->reg().existingEntry(key.text(),"filter-mode")) { FXuint mode = getApp()->reg().readIntEntry(key.text(),"filter-mode",0); switch(mode){ case 0 : filtermask=FILTER_TRACK|FILTER_ALBUM|FILTER_ARTIST; break; case 1 : filtermask=FILTER_ARTIST; break; case 2 : filtermask=FILTER_ALBUM; break; case 3 : filtermask=FILTER_TRACK; break; default: filtermask=FILTER_DEFAULT; break; } getApp()->reg().deleteEntry(key.text(),"filter-mode"); #if FOXVERSION < FXVERSION(1,7,0) getApp()->reg().writeUnsignedEntry(key.text(),"filter-mask",filtermask); #else getApp()->reg().writeUIntEntry(key.text(),"filter-mask",filtermask); #endif } else { #if FOXVERSION < FXVERSION(1,7,0) filtermask = getApp()->reg().readUnsignedEntry(key.text(),"filter-mask",FILTER_DEFAULT); #else filtermask = getApp()->reg().readUIntEntry(key.text(),"filter-mask",FILTER_DEFAULT); #endif } if (source) source->setFilter(filterfield->getText().trim().simplify(),filtermask); loadTrackSettings(key); } void GMTrackView::loadTrackSettings(const FXString & key) { FXString browseprefix = (browsersplit->getExpanded()==SHOWBROWSER) ? "browse" : "list"; FXString name; tracklist->clearHeaders(); for (FXint i=0;ireg().readBoolEntry(key.text(),FXString(browseprefix+"-showcolumn-"+name).text(),(browsersplit->getExpanded()==SHOWBROWSER) ? columns[i].default_browser_show : columns[i].default_show); columns[i].size = getApp()->reg().readIntEntry(key.text(),FXString(browseprefix+"-columnwidth-"+name).text(),columns[i].size); columns[i].index = getApp()->reg().readIntEntry(key.text(),FXString(browseprefix+"-columnindex-"+name).text(),columns[i].index); if (columns[i].show) { tracklist->appendHeader(fxtr(columns[i].name.text()),columns[i].size,&columns[i]); } } FXint sort = getApp()->reg().readIntEntry(key.text(),FXString(browseprefix+"-sort-column").text(),source->getSortColumn(browsersplit->getExpanded()==SHOWBROWSER)); FXbool reverse = getApp()->reg().readBoolEntry(key.text(),FXString(browseprefix+"-sort-reverse").text(),false); #if FOXVERSION < FXVERSION(1,7,0) sort_seed = getApp()->reg().readUnsignedEntry(key.text(),FXString(browseprefix+"-sort-seed").text(),(FXuint)FXSystem::now()); #else sort_seed = getApp()->reg().readUIntEntry(key.text(),FXString(browseprefix+"-sort-seed").text(),(FXuint)FXThread::time()); #endif setSortMethod(sort,reverse); } void GMTrackView::saveSettings(const FXString & key) const { getApp()->reg().writeBoolEntry(key.text(),"genre-list-sort-reverse",genrelist->getSortFunc()==genre_list_sort_reverse); getApp()->reg().writeBoolEntry(key.text(),"artist-list-sort-reverse",artistlist->getSortFunc()==artist_list_sort_reverse); getApp()->reg().writeBoolEntry(key.text(),"album-list-sort-reverse",albumlist->getSortFunc()==album_list_sort_reverse); getApp()->reg().writeBoolEntry(key.text(),"album-list-sort-by-year",album_by_year); getApp()->reg().writeBoolEntry(key.text(),"genre-list",genrelistframe->shown()); getApp()->reg().writeBoolEntry(key.text(),"browser",browsersplit->getExpanded()==SHOWBROWSER); getApp()->reg().writeIntEntry(key.text(),"browser-track-split",browsersplit->getVSplit()); getApp()->reg().writeIntEntry(key.text(),"artist-album-split",browsersplit->getHSplit()); getApp()->reg().writeIntEntry(key.text(),"genre-artist-split",genresplit->getHSplit()); #if FOXVERSION < FXVERSION(1,7,0) getApp()->reg().writeIntEntry(key.text(),"track-list-posx",tracklist->getXPosition()); getApp()->reg().writeIntEntry(key.text(),"track-list-posy",tracklist->getYPosition()); #else getApp()->reg().writeIntEntry(key.text(),"track-list-posx",tracklist->getContentX()); getApp()->reg().writeIntEntry(key.text(),"track-list-posy",tracklist->getContentY()); #endif getApp()->reg().writeBoolEntry(key.text(),"filter",filterframe->shown()); if (filterframe->shown() && !filterfield->getText().empty()) { getApp()->reg().writeStringEntry(key.text(),"filter-text",filterfield->getText().text()); #if FOXVERSION < FXVERSION(1,7,0) getApp()->reg().writeUnsignedEntry(key.text(),"filter-mask",filtermask); #else getApp()->reg().writeUIntEntry(key.text(),"filter-mask",filtermask); #endif } else{ getApp()->reg().writeStringEntry(key.text(),"filter-text",""); #if FOXVERSION < FXVERSION(1,7,0) getApp()->reg().writeUnsignedEntry(key.text(),"filter-mask",FILTER_DEFAULT); #else getApp()->reg().writeUIntEntry(key.text(),"filter-mask",FILTER_DEFAULT); #endif } saveTrackSettings(key); } void GMTrackView::saveTrackSettings(const FXString & key) const { tracklist->saveHeaders(); FXString browseprefix = (browsersplit->getExpanded()==SHOWBROWSER) ? "browse" : "list"; FXString name; for (FXint i=0;ireg().writeBoolEntry(key.text(),FXString(browseprefix+"-showcolumn-"+name.lower()).text(),columns[i].show); getApp()->reg().writeIntEntry(key.text(),FXString(browseprefix+"-columnwidth-"+name.lower()).text(),columns[i].size); getApp()->reg().writeIntEntry(key.text(),FXString(browseprefix+"-columnindex-"+name.lower()).text(),columns[i].index); } getApp()->reg().writeIntEntry(key.text(),FXString(browseprefix+"-sort-column").text(),tracklist->getSortMethod()); getApp()->reg().writeBoolEntry(key.text(),FXString(browseprefix+"-sort-reverse").text(),getSortReverse()); #if FOXVERSION < FXVERSION(1,7,0) getApp()->reg().writeUnsignedEntry(key.text(),FXString(browseprefix+"-sort-seed").text(),sort_seed); #else getApp()->reg().writeUIntEntry(key.text(),FXString(browseprefix+"-sort-seed").text(),sort_seed); #endif } long GMTrackView::onCmdShowColumn(FXObject*,FXSelector sel,void*){ FXint no=FXSELID(sel)-ID_COLUMN_FIRST; for (FXint i=0;iclearHeaders(); for (FXint i=0;iappendHeader(fxtr(columns[i].name.text()),columns[i].size,&columns[i]); } } return 1; } long GMTrackView::onUpdShowColumn(FXObject*sender,FXSelector sel,void*){ if (columns.no()) { FXint no=FXSELID(sel)-ID_COLUMN_FIRST; for (FXint i=0;ihandle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),&column); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SHOW),NULL); if (columns[i].show) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); return 1; } } } sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_HIDE),NULL); return 1; } long GMTrackView::onCmdSort(FXObject*,FXSelector sel,void*){ FXint no=FXSELID(sel)-ID_SORT_FIRST; tracklist->setSortMethod(columns[no].type); tracklist->setSortFunc(columns[no].ascending); sortTracks(); return 1; } long GMTrackView::onUpdSort(FXObject*sender,FXSelector sel,void*){ if (columns.no()) { FXMenuCommand * cmd = dynamic_cast(sender); FXASSERT(cmd); FXint no=FXSELID(sel)-ID_SORT_FIRST; if (nosetText(GMStringFormat(fxtrformat("By %s"),fxtr(columns[no].name.text()))); if (columns[no].type==source->getSortColumn(browsersplit->getExpanded()==SHOWBROWSER)) cmd->setAccelText("Ctrl-N"); else cmd->setAccelText(FXString::null); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SHOW),NULL); if (tracklist->getSortMethod()==columns[no].type) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_HIDE),NULL); } } else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_HIDE),NULL); return 1; } long GMTrackView::onUpdSortReverse(FXObject*sender,FXSelector,void*){ for (FXint i=0;igetSortMethod()==columns[i].type) { sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); if (tracklist->getSortFunc()==columns[i].descending) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } } sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMTrackView::onCmdSortDefault(FXObject*,FXSelector,void*){ FXint def = source->getSortColumn(browsersplit->getExpanded()==SHOWBROWSER); setSortMethod(def); sortTracks(); return 1; } long GMTrackView::onCmdSortBrowse(FXObject*,FXSelector,void*){ setSortMethod(HEADER_BROWSE); sortTracks(); return 1; } long GMTrackView::onUpdSortBrowse(FXObject*sender,FXSelector,void*){ if ((browsersplit->getExpanded()==SHOWBROWSER) && source && source->getSortBrowse()) { sender->handle(this,FXSEL(SEL_COMMAND,ID_SHOW),NULL); if (tracklist->getSortMethod()==HEADER_BROWSE) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); FXMenuCommand * cmd = dynamic_cast(sender); FXASSERT(cmd); if (HEADER_BROWSE==source->getSortColumn(browsersplit->getExpanded()==SHOWBROWSER)) cmd->setAccelText("Ctrl-N"); else cmd->setAccelText(FXString::null); } else sender->handle(this,FXSEL(SEL_COMMAND,ID_HIDE),NULL); return 1; } long GMTrackView::onCmdSortShuffle(FXObject*,FXSelector,void*){ tracklist->setSortMethod(HEADER_SHUFFLE); #if FOXVERSION < FXVERSION(1,7,0) sort_seed = (FXuint)FXSystem::now(); #else sort_seed = (FXuint)FXThread::time(); #endif sortTracks(); return 1; } long GMTrackView::onUpdSortShuffle(FXObject*sender,FXSelector,void*){ if (tracklist->getSortMethod()==HEADER_SHUFFLE) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMTrackView::onCmdSortGenreList(FXObject*,FXSelector,void*){ if (genrelist->getSortFunc()==genre_list_sort) { genrelist->setSortFunc(genre_list_sort_reverse); genrelistheader->setArrowState(ARROW_UP); } else { genrelist->setSortFunc(genre_list_sort); genrelistheader->setArrowState(ARROW_DOWN); } sortGenres(); return 1; } long GMTrackView::onCmdSortArtistList(FXObject*,FXSelector,void*){ if (artistlist->getSortFunc()==artist_list_sort) { artistlist->setSortFunc(artist_list_sort_reverse); reverse_artist=true; artistlistheader->setArrowState(ARROW_UP); } else { artistlist->setSortFunc(artist_list_sort); reverse_artist=false; artistlistheader->setArrowState(ARROW_DOWN); } sortArtists(); if (tracklist->getSortMethod()==HEADER_BROWSE) sortTracks(); return 1; } long GMTrackView::onCmdSortAlbumList(FXObject*,FXSelector,void*){ if (albumlist->getSortFunc()==album_list_sort) { albumlist->setSortFunc(album_list_sort_reverse); reverse_album=true; albumlistheader->setArrowState(ARROW_UP); } else { albumlist->setSortFunc(album_list_sort); reverse_album=false; albumlistheader->setArrowState(ARROW_DOWN); } sortAlbums(); if (tracklist->getSortMethod()==HEADER_BROWSE) sortTracks(); if (getApp()->hasChore(this,ID_LOAD_ALBUM_ICONS)) getApp()->addChore(this,ID_LOAD_ALBUM_ICONS,(void*)(FXival)0); return 1; } long GMTrackView::onCmdGenreSelected(FXObject*,FXSelector sel,void*ptr){ if ( FXSELTYPE(sel)==SEL_COMMAND ) { if (genre_selectionchanged>=0) { artistlist->clearItems(); albumlist->clearItems(); tracklist->clearItems(); listArtists(); listAlbums(); listTracks(); genre_selectionchanged=-1; } } else { /* Make sure "All Genre" is not selected at the same time as the other items and vice-versa. */ if ( (FXSELTYPE(sel)==SEL_SELECTED) && genrelist->getNumItems()>1 ){ if (((FXint)(FXival)ptr)==0) { genrelist->killSelection(); genrelist->selectItem(0); } else if (genrelist->isItemSelected(0)){ genrelist->deselectItem(0); } } if ((FXSELTYPE(sel)==SEL_DESELECTED) && genrelist->getNumItems()==1){ genrelist->selectItem(0); return 1; } if (genre_selectionchanged==(FXint)(FXival)ptr) genre_selectionchanged=-1; else genre_selectionchanged=(FXint)(FXival)ptr; } return 1; } long GMTrackView::onCmdArtistSelected(FXObject*,FXSelector sel,void*ptr){ if ( FXSELTYPE(sel)==SEL_DOUBLECLICKED) { GMPlayerManager::instance()->play(); } else if ( FXSELTYPE(sel)==SEL_COMMAND ) { if (artist_selectionchanged>=0) { albumlist->clearItems(); tracklist->clearItems(); listAlbums(); listTracks(); artist_selectionchanged=-1; } } else { /* Make sure "All Artist" is not selected at the same time as the other items and vice-versa. */ if ( (FXSELTYPE(sel)==SEL_SELECTED) && artistlist->getNumItems()>1 ){ if (((FXint)(FXival)ptr)==0) { artistlist->killSelection(); artistlist->selectItem(0); } else if (artistlist->isItemSelected(0)){ artistlist->deselectItem(0); } } if ((FXSELTYPE(sel)==SEL_DESELECTED) && artistlist->getNumItems()==1){ artistlist->selectItem(0); return 1; } if (artist_selectionchanged==(FXint)(FXival)ptr) artist_selectionchanged=-1; else artist_selectionchanged=(FXint)(FXival)ptr; } return 1; } long GMTrackView::onCmdAlbumSelected(FXObject*,FXSelector sel,void*ptr){ if ( FXSELTYPE(sel)==SEL_DOUBLECLICKED) { GMPlayerManager::instance()->play(); } else if ( FXSELTYPE(sel)==SEL_COMMAND ) { if (album_selectionchanged>=0) { tracklist->clearItems(); listTracks(); album_selectionchanged=-1; } } else { /* Make sure "All Albums" is not selected at the same time as the other items and vice-versa. */ if ( (FXSELTYPE(sel)==SEL_SELECTED) && albumlist->getNumItems()>1 ){ if (((FXint)(FXival)ptr)==0) { albumlist->killSelection(); albumlist->selectItem(0); } else if (albumlist->isItemSelected(0)){ albumlist->deselectItem(0); } } if (album_selectionchanged==(FXint)(FXival)ptr) album_selectionchanged=-1; else album_selectionchanged=(FXint)(FXival)ptr; } return 1; } long GMTrackView::onGenreContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (source && !event->moved) { FXint item = genrelist->getItemAt(event->win_x,event->win_y); if (item>=0 && getGenre(item)!=-1) { GMMenuPane pane(this); if (source->genre_context_menu(&pane)) { selectGenreItem(item); pane.create(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); } } return 1; } return 0; } long GMTrackView::onArtistContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (source && !event->moved) { FXint item = artistlist->getItemAt(event->win_x,event->win_y); if (item>=0 && getArtist(item)!=-1) { GMMenuPane pane(this); if (source->artist_context_menu(&pane)) { selectArtistItem(item); selectAlbumItem(0); pane.create(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); } } return 1; } return 0; } long GMTrackView::onAlbumContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); FXbool old = album_by_year; FXDataTarget target_yearsort(album_by_year); if (source && !event->moved) { GMMenuPane pane(this); FXint item = albumlist->getItemAt(event->win_x,event->win_y); if (item>=0 && getAlbum(item)!=-1 && source->album_context_menu(&pane)) selectAlbumItem(item); new GMMenuCheck(&pane,fxtr("Sort by Album Year"),&target_yearsort,FXDataTarget::ID_VALUE); pane.create(); pane.forceRefresh(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); if (old!=album_by_year){ sortAlbums(); sortTracks(); } return 1; } return 0; } long GMTrackView::onAlbumHeaderContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); FXbool old = album_by_year; FXDataTarget target_yearsort(album_by_year); if (source && !event->moved) { GMMenuPane pane(this); new GMMenuCheck(&pane,fxtr("Sort by Album Year"),&target_yearsort,FXDataTarget::ID_VALUE); pane.create(); pane.forceRefresh(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); if (old!=album_by_year){ sortAlbums(); sortTracks(); } return 1; } return 0; } long GMTrackView::onTrackContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (source && !event->moved) { GMMenuPane pane(this); FXint item = tracklist->getItemAt(event->win_x,event->win_y); if (item>=0 && !tracklist->isItemSelected(item)) selectTrackItem(item); if (item>=0 && source->track_context_menu(&pane)) new FXMenuSeparator(&pane); new GMMenuCascade(&pane,tr("&Columns\t\tChange Visible Columns."),NULL,columnmenu); new GMMenuCascade(&pane,tr("&Sort\t\tChange Sorting."),GMIconTheme::instance()->icon_sort,sortmenu); pane.create(); ewmh_change_window_type(columnmenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(sortmenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); return 1; } return 0; } long GMTrackView::onTrackHeaderContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (source && !event->moved) { columnmenu->create(); ewmh_change_window_type(columnmenu,WINDOWTYPE_POPUP_MENU); columnmenu->popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(columnmenu); return 1; } return 0; } long GMTrackView::onCmdGenreKeyPress(FXObject*,FXSelector,void*ptr){ FXEvent* event=reinterpret_cast(ptr); if (event->state&(CONTROLMASK) && (event->code==KEY_A || event->code==KEY_a)) { if (genrelist->getNumItems()) { selectGenreItem(0); genrelist->makeItemVisible(0); } return 1; } else if (event->code==KEY_Delete || event->code==KEY_KP_Delete) { if (source && genrelist->getNumItems()) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_DELETE_GENRE),NULL); } return 1; } // else if (event->code==KEY_F2) { // if (source && genrelist->getNumItems()) { // source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_EDIT_GENRE),NULL); // } // return 1; // } return 0; } long GMTrackView::onCmdArtistKeyPress(FXObject*,FXSelector,void*ptr){ FXEvent* event=reinterpret_cast(ptr); if (event->state&(CONTROLMASK) && (event->code==KEY_A || event->code==KEY_a)) { if (artistlist->getNumItems()) { selectArtistItem(0); artistlist->makeItemVisible(0); } return 1; } else if (event->code==KEY_Delete || event->code==KEY_KP_Delete) { if (source && artistlist->getNumItems()) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_DELETE_ARTIST),NULL); } return 1; } // else if (event->code==KEY_F2) { // if (source && artistlist->getNumItems()) { // source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_EDIT_ARTIST),NULL); // } // return 1; // } else if (!(event->state&CONTROLMASK)){ FXString text; FXint a; for (FXint i=0;igetNumItems();i++){ text=artistlist->getItemText(i); if (begins_with_keyword(text)) a=FXMIN(text.length()-1,text.find(' ')+1); else a=0; if (comparecase(&text[a],event->text,1)==0){ selectArtistItem(i); artistlist->makeItemVisible(i); break; } } } return 0; } long GMTrackView::onCmdAlbumKeyPress(FXObject*,FXSelector,void*ptr){ FXEvent* event=reinterpret_cast(ptr); if (event->state&(CONTROLMASK) && (event->code==KEY_A || event->code==KEY_a)) { if (albumlist->getNumItems()) { selectAlbumItem(0); albumlist->makeItemVisible(0); } return 1; } else if (event->code==KEY_Delete || event->code==KEY_KP_Delete) { if (source && albumlist->getNumItems()) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_DELETE_ALBUM),NULL); } return 1; } // else if (event->code==KEY_F2) { // if (source && albumlist->getNumItems()) { // source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_EDIT_ALBUM),NULL); // } // return 1; // } return 0; } long GMTrackView::onCmdTrackKeyPress(FXObject*,FXSelector,void*ptr){ FXEvent* event=reinterpret_cast(ptr); if (event->state&(CONTROLMASK) ) { if (event->code==KEY_A || event->code==KEY_a) { if (tracklist->getNumItems()){ tracklist->setAnchorItem(0); tracklist->selectItem(0); tracklist->extendSelection(tracklist->getNumItems()-1); } return 1; } else if (event->code==KEY_C || event->code==KEY_c) { if (source && numTrackSelected() ) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_COPY_TRACK),NULL); } return 1; } } else if (event->code==KEY_Delete || event->code==KEY_KP_Delete) { if (source && numTrackSelected() ) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_DELETE_TRACK),NULL); } return 1; } else if (event->code==KEY_F2) { if (source && numTrackSelected()) { source->handle(this,FXSEL(SEL_COMMAND,GMSource::ID_EDIT_TRACK),NULL); } return 1; } return 0; } long GMTrackView::onCmdPlayTrack(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->play(); tracklist->deselectItem(tracklist->getCurrentItem()); return 1; } long GMTrackView::onCmdShowCurrent(FXObject*,FXSelector,void*){ if (!source->findCurrent(tracklist,GMPlayerManager::instance()->getSource())){ if (source->hasCurrentTrack(GMPlayerManager::instance()->getSource())){ refresh(); } else { GMPlayerManager::instance()->getSourceView()->setSource(GMPlayerManager::instance()->getSource()); if (!source->findCurrent(tracklist,GMPlayerManager::instance()->getSource())){ if (source->hasCurrentTrack(GMPlayerManager::instance()->getSource())){ refresh(); } } } } return 1; } long GMTrackView::onUpdShowCurrent(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMTrackView::onCmdPaste(FXObject*sender,FXSelector,void*ptr){ return source && source->handle(sender,FXSEL(SEL_COMMAND,GMSource::ID_PASTE),ptr); } long GMTrackView::onUpdPaste(FXObject*sender,FXSelector,void*ptr){ return source && source->handle(sender,FXSEL(SEL_UPDATE,GMSource::ID_PASTE),ptr); } long GMTrackView::onCmdCopy(FXObject*sender,FXSelector,void*ptr){ return source && source->handle(sender,FXSEL(SEL_COMMAND,GMSource::ID_COPY_TRACK),ptr); } long GMTrackView::onUpdCopy(FXObject*sender,FXSelector,void*){ if (trackSelected() && source) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMTrackView::onCmdFilter(FXObject*,FXSelector sel,void*){ if (FXSELID(sel)==ID_FILTER_MODE && filterfield->getText().empty()) return 1; if (FXSELTYPE(sel)==SEL_CHANGED) { getApp()->addTimeout(this,ID_FILTER,TIME_MSEC(500)); return 1; } if (FXSELTYPE(sel)==SEL_COMMAND){ getApp()->removeTimeout(this,ID_FILTER); } if (source->setFilter(filterfield->getText().trim().simplify(),filtermask)) refresh(); return 1; } long GMTrackView::onCmdFilterMask(FXObject*,FXSelector sel,void*){ switch(FXSELID(sel)){ case ID_FILTER_TRACK : filtermask ^= FILTER_TRACK; break; case ID_FILTER_ALBUM : filtermask ^= FILTER_ALBUM; break; case ID_FILTER_ARTIST : filtermask ^= FILTER_ARTIST; break; case ID_FILTER_GENRE : filtermask ^= FILTER_GENRE; break; } getApp()->addTimeout(this,ID_FILTER,TIME_MSEC(500)); return 1; } long GMTrackView::onUpdFilterMask(FXObject*sender,FXSelector sel,void*){ FXbool check=false; switch(FXSELID(sel)){ case ID_FILTER_TRACK: check = (filtermask&FILTER_TRACK)!=0; break; case ID_FILTER_ALBUM: check = (filtermask&FILTER_ALBUM)!=0; break; case ID_FILTER_ARTIST: check = (filtermask&FILTER_ARTIST)!=0; break; case ID_FILTER_GENRE: check = (filtermask&FILTER_GENRE)!=0; break; } if (check) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMTrackView::onCmdBeginDrag(FXObject*sender,FXSelector sel,void*){ FXWindow * window = (FXWindow*)sender; if (FXSELID(sel)==ID_ALBUM_LIST) { /* we don't seem to get a SEL_COMMAND message when we start dragging */ if (album_selectionchanged>=0) { tracklist->clearItems(); listTracks(); album_selectionchanged=-1; } FXDragType types[]={GMClipboard::kdeclipboard,GMClipboard::urilistType,GMClipboard::alltracks}; if (window->beginDrag(types,3)){ } } else if (FXSELID(sel)==ID_TRACK_LIST){ FXDragType types[]={GMClipboard::kdeclipboard,GMClipboard::urilistType,GMClipboard::selectedtracks}; if (window->beginDrag(types,3)){ } } else if (FXSELID(sel)==ID_ARTIST_LIST){ /* we don't seem to get a SEL_COMMAND message when we start dragging */ if (artist_selectionchanged>=0) { albumlist->clearItems(); tracklist->clearItems(); listAlbums(); listTracks(); artist_selectionchanged=-1; } FXDragType types[]={GMClipboard::kdeclipboard,GMClipboard::urilistType,GMClipboard::alltracks}; if (window->beginDrag(types,3)){ } } else { return 0; } return 1; } long GMTrackView::onCmdDragged(FXObject*sender,FXSelector,void*ptr){ FXWindow * window = (FXWindow*)sender; FXEvent* event=(FXEvent*)ptr; FXDragAction action=DRAG_COPY; if(event->state&ALTMASK) action=DRAG_LINK; window->handleDrag(event->root_x,event->root_y,action); action=window->didAccept(); if (window->didAccept()!=DRAG_REJECT) { if (action==DRAG_MOVE) window->setDragCursor(getApp()->getDefaultCursor(DEF_DNDMOVE_CURSOR)); else if (action==DRAG_LINK) window->setDragCursor(getApp()->getDefaultCursor(DEF_DNDLINK_CURSOR)); else window->setDragCursor(getApp()->getDefaultCursor(DEF_DNDCOPY_CURSOR)); } else { window->setDragCursor(getApp()->getDefaultCursor(DEF_DNDSTOP_CURSOR)); } return 1; } long GMTrackView::onCmdEndDrag(FXObject*sender,FXSelector,void*){ FXWindow * window = (FXWindow*)sender; if (getApp()->getDragWindow()==tracklist) window->endDrag(window->didAccept()!=DRAG_REJECT); else window->endDrag((window->didAccept()!=DRAG_MOVE && window->didAccept()!=DRAG_REJECT)); window->setDragCursor(window->getDefaultCursor()); return 1; } long GMTrackView::onDndTrackEnter(FXObject*,FXSelector,void*){ tracklist_dragging=1; tracklist_lastline=-1; return 0; } long GMTrackView::onDndTrackLeave(FXObject*,FXSelector,void*){ tracklist_dragging=0; if (tracklist_lastline>=0) { tracklist->update(0,tracklist_lastline,tracklist->getHeader()->getDefaultWidth(),1); } tracklist_lastline=-1; return 0; } long GMTrackView::onDndTrackMotion(FXObject*,FXSelector,void*ptr){ FXEvent* event=(FXEvent*)ptr; if (getApp()->getDragWindow()==tracklist) { if (tracklist->offeredDNDType(FROM_DRAGNDROP,GMClipboard::selectedtracks)){ FXint pos_x,pos_y,item; tracklist->getPosition(pos_x,pos_y); item = (event->win_y-pos_y-tracklist->getHeader()->getDefaultHeight())/tracklist->getLineHeight(); if (item<0) item=0; if (item>=tracklist->getNumItems()) { tracklist->acceptDrop(DRAG_REJECT); return 1; } FXint ds = pos_y+item*tracklist->getLineHeight()+tracklist->getHeader()->getDefaultHeight(); FXint dm = ds + (tracklist->getLineHeight()/2); FXint dl=0; tracklist_dropitem=item; if (event->win_y<=dm) { dl = ds; } else { dl = ds+tracklist->getLineHeight(); tracklist_dropitem=FXMIN(item+1,tracklist->getNumItems()); } FXDCWindow dc(tracklist); dc.setForeground(FXRGB(0,0,0)); dc.fillRectangle(0,dl,tracklist->getHeader()->getDefaultWidth(),1); if (tracklist_lastline>=0 && (tracklist_lastline!=dl || tracklist_lastposy!=pos_y)) { tracklist->update(0,tracklist_lastline-(tracklist_lastposy-pos_y),tracklist->getHeader()->getDefaultWidth(),1); } tracklist_lastline=dl; tracklist_lastposy=pos_y; tracklist->acceptDrop(DRAG_MOVE); return 1; } } else if (getApp()->getDragWindow()==NULL) { FXDragType * types; FXuint ntypes; if (tracklist->inquireDNDTypes(FROM_DRAGNDROP,types,ntypes)){ if (source->dnd_source_accepts(types,ntypes)){ tracklist->acceptDrop(DRAG_LINK); freeElms(types); return 1; } } freeElms(types); } tracklist->acceptDrop(DRAG_REJECT); return 1; } long GMTrackView::onDndTrackDrop(FXObject*sender,FXSelector,void*ptr){ if (getApp()->getDragWindow()==tracklist) { if (!tracklist->offeredDNDType(FROM_DRAGNDROP,GMClipboard::selectedtracks)) return 1; if (tracklist_lastline>=0) { tracklist->update(0,tracklist_lastline,tracklist->getHeader()->getDefaultWidth(),1); } tracklist_dragging=1; tracklist_lastline=-1; FXint i,tgt; FXbool srcmoved=false; for (i=tracklist->getNumItems()-1;i>=0;i--){ if (tracklist->isItemSelected(i) && (i+1)!=tracklist_dropitem) { if (imoveTrack(tracklist,i,tgt); tracklist->moveItem(tgt,i); tracklist->deselectItem(tgt); if (iorderChanged(tracklist); } } if (srcmoved==false) tracklist->markUnsorted(); tracklist->dropFinished(DRAG_ACCEPT); if (GMPlayerManager::instance()->playing() && GMPlayerManager::instance()->getSource()) source->findCurrent(tracklist,GMPlayerManager::instance()->getSource()); return 1; } else if (source && getApp()->getDragWindow()==NULL) { return source->handle(sender,FXSEL(SEL_DND_DROP,GMSource::ID_DROP),ptr); } return 0; } long GMTrackView::onDndMotion(FXObject*,FXSelector,void*){ if (getApp()->getDragWindow()==NULL && source) { FXDragType * types; FXuint ntypes; if (tracklist->inquireDNDTypes(FROM_DRAGNDROP,types,ntypes)){ if (source->dnd_source_accepts(types,ntypes)){ tracklist->acceptDrop(DRAG_ACCEPT); freeElms(types); return 1; } } freeElms(types); } return 0; } long GMTrackView::onDndDrop(FXObject*sender,FXSelector,void*ptr){ if (getApp()->getDragWindow()==NULL && source) { return source->handle(sender,FXSEL(SEL_DND_DROP,GMSource::ID_DROP),ptr); } return 0; } long GMTrackView::onDndRequest(FXObject*sender,FXSelector sel,void*ptr){ if (source) { switch(FXSELID(sel)){ case ID_TRACK_LIST : return source->handle(sender,FXSEL(SEL_DND_REQUEST,GMSource::ID_COPY_TRACK),ptr); break; case ID_ALBUM_LIST : return source->handle(sender,FXSEL(SEL_DND_REQUEST,GMSource::ID_COPY_ALBUM),ptr); break; case ID_ARTIST_LIST: return source->handle(sender,FXSEL(SEL_DND_REQUEST,GMSource::ID_COPY_ARTIST),ptr); break; default : break; } } return 0; } long GMTrackView::onCmdToggleBrowser(FXObject*,FXSelector,void*){ if (source) saveTrackSettings(source->settingKey()); if (browsersplit->getExpanded()==SHOWBROWSER) browsersplit->setExpanded(HIDEBROWSER); else browsersplit->setExpanded(SHOWBROWSER); if (source) loadTrackSettings(source->settingKey()); refresh(); return 1; } long GMTrackView::onUpdToggleBrowser(FXObject*sender,FXSelector,void*){ if (source && source->canBrowse()) { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); if (browsersplit->getExpanded()==SHOWBROWSER) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); } return 1; } long GMTrackView::onCmdToggleGenres(FXObject*,FXSelector,void*){ if (genrelistframe->shown()) { genrelistframe->hide(); genrelist->killSelection(false); genrelist->selectItem(0,true); genrelistframe->recalc(); browsersplit->setHSplit(5000); } else { genrelistframe->show(); genrelistframe->recalc(); genresplit->setHSplit(5000); browsersplit->setHSplit(6666); } return 1; } long GMTrackView::onUpdToggleGenres(FXObject*sender,FXSelector,void*){ if (source && source->canBrowse() && browsersplit->getExpanded()==SHOWBROWSER) { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); if (genrelistframe->shown()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); } return 1; } long GMTrackView::onCmdToggleFilter(FXObject*,FXSelector sel,void*){ if (filterframe->shown() && FXSELID(sel)==ID_CLOSE_FILTER) { filterframe->hide(); if (!filterfield->getText().empty()){ source->setFilter(FXString::null,filtermask); refresh(); } recalc(); } else { filterframe->show(); filterfield->setFocus(); if (!filterfield->getText().empty()) filterfield->setSelection(0,filterfield->getText().length()); recalc(); } return 1; } long GMTrackView::onUpdToggleFilter(FXObject*sender,FXSelector,void*){ if (source && source->canFilter()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMTrackView::onCmdConfigureColumns(FXObject*,FXSelector,void*){ GMColumnDialog dialog(getShell(),columns); if (dialog.execute()) { dialog.saveIndex(); tracklist->clearHeaders(); for (FXint i=0;iappendHeader(fxtr(columns[i].name.text()),columns[i].size,&columns[i]); } } } return 1; } long GMTrackView::onCmdLoadAlbumIcons(FXObject*,FXSelector,void*ptr){ FXint item=(FXint)(FXival)ptr; if (item>=albumlist->getNumItems()) return 1; while(itemgetNumItems()){ if (albumlist->getItemIcon(item)!=GMIconTheme::instance()->icon_nocover) { item++; continue; } FXint album=(FXint)(FXival)albumlist->getItemData(item); if (album==-1){ item++; continue; } FXIcon * icon = source->getAlbumIcon(album,false); if (icon) albumlist->setItemIcon(item,icon); break; } item++; if (item>=albumlist->getNumItems()) return 1; getApp()->addChore(this,ID_LOAD_ALBUM_ICONS,(void*)(FXival)item); return 1; } gogglesmm-0.12.7/src/GMURL.h0000644000175000001440000000623411525430601014135 0ustar sxjusers/******************************************************************************** * * * U R L M a n i p u l a t i o n * * * ********************************************************************************* * Copyright (C) 2000,2011 by Jeroen van der Zijp. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see * ********************************************************************************* * $Id: FXURL.h,v 1.23 2008/06/02 14:19:51 fox Exp $ * ********************************************************************************/ #ifndef GMURL_H #define GMURL_H #if FOXVERSION < FXVERSION(1,7,0) namespace GMURL { /// Encode control characters and characters from set using %-encoding extern FXAPI FXString encode(const FXString& string,const FXchar* set=NULL); /// Decode string containing %-encoded characters extern FXAPI FXString decode(const FXString& string); /// Parse scheme from string containing url extern FXAPI FXString scheme(const FXString& string); /// Parse username from string containing url extern FXAPI FXString username(const FXString& string); /// Parse password from string containing url extern FXAPI FXString password(const FXString& string); /// Parse hostname from string containing url extern FXAPI FXString host(const FXString& string); /// Parse port number from string containing url extern FXAPI FXint port(const FXString& string); /// Parse path from string containing url extern FXAPI FXString path(const FXString& string); /// Parse query from string containing url extern FXAPI FXString query(const FXString& string); /// Parse fragment from string containing url extern FXAPI FXString fragment(const FXString& string); /// Return URL of filename extern FXAPI FXString fileToURL(const FXString& string); /// Return filename from URL, empty if url is not a local file extern FXAPI FXString fileFromURL(const FXString& string); } #else #define GMURL FXURL #endif #else #error GMURL already included #endif gogglesmm-0.12.7/src/GMDatabase.h0000644000175000001440000000620411525430601015174 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMDATABASE_H #define GMDATABASE_H class GMQuery; class GMDatabase { friend class GMQuery; private: FXbool opened; GMDatabaseEngine * db; public: /// Constructor: database is not opened GMDatabase(); /// Open Database; Return TRUE if succeeds else FALSE FXbool open(const FXString & filename); /// Return error message of last failed function const FXchar * getError(); /// Return TRUE if database is opened FXbool isOpen() { return opened; } /// Close Database void close(); /// Clear Database void clear(); /// Clear Tables void clearTables(); /// Begin Transaction FXbool begin(); /// Commit Transaction() FXbool commit(); /// Rollback a transaction FXbool rollback(); /// End Transaction FXbool end(); /// Return Last Inserted Row Id FXint lastInsertRow(); FXint changes() const; /// Set Version void setVersion(FXint v); /// Get Version FXint getVersion(); /// Return TRUE if table exists FXbool hasTable(const FXString & table); /// Return TRUE if view exists FXbool hasView(const FXString & view); /// Return TRUE if index exists FXbool hasIndex(const FXString & index); /// Return a list of tables in the database void listTables(FXStringList & list); /// Return a list of views in the database void listViews(FXStringList & list); /// Return num changes by recent query FXint getNumChanges() const; /// Return total changes since opening database FXint getTotalChanges() const; /// Execute Simple Query FXbool execute(const FXchar * query); FXbool execute(const FXString & query); FXbool execute_with_result(const FXString & query,FXint & val); /// Close Database virtual ~GMDatabase(); }; #endif gogglesmm-0.12.7/src/GMTrayIcon.cpp0000644000175000001440000002637711573753471015610 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "xincs.h" #include "icons.h" #include "FXPNGIcon.h" #include "GMRemote.h" #include "GMList.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMWindow.h" #include "GMApp.h" #include "GMTrayIcon.h" #include "GMIconTheme.h" enum { SYSTEM_TRAY_REQUEST_DOCK =0, SYSTEM_TRAY_BEGIN_MESSAGE =1, SYSTEM_TRAY_CANCEL_MESSAGE=2, }; enum { SYSTEM_TRAY_HORIZONTAL = 0, SYSTEM_TRAY_VERTICAL = 1, SYSTEM_TRAY_UNKNOWN = 2 }; FXDEFMAP(GMTrayIcon) GMTrayIconMap[]={ FXMAPFUNC(SEL_PAINT,0,GMTrayIcon::onPaint), FXMAPFUNC(SEL_CONFIGURE,0,GMTrayIcon::onConfigure), FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,GMTrayIcon::onLeftBtnPress), FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,0,GMTrayIcon::onMiddleBtnPress), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,0,GMTrayIcon::onRightBtnRelease), FXMAPFUNC(SEL_MOUSEWHEEL,0,GMTrayIcon::onMouseWheel), FXMAPFUNC(SEL_QUERY_TIP,0,GMTrayIcon::onQueryTip) }; FXIMPLEMENT(GMTrayIcon,GMPlug,GMTrayIconMap,ARRAYNUMBER(GMTrayIconMap)); GMTrayIcon::GMTrayIcon(){ icon=NULL; flags|=FLAG_ENABLED; } GMTrayIcon::GMTrayIcon(FXApp * app) : GMPlug(app), xtraywindow(0), xtrayopcode(0),icon(NULL), opaque(false) { flags|=FLAG_ENABLED; } GMTrayIcon::~GMTrayIcon(){ if (icon) delete icon; } void GMTrayIcon::display(const GMTrack &track){ setToolTip(GMStringFormat("%s\n%s\n%s (%d)",track.title.text(),track.artist.text(),track.album.text(),track.year)); } void GMTrayIcon::reset() { setToolTip(FXString::null); } void GMTrayIcon::updateIcon() { if (icon) { FXint size = icon->getWidth(); /// Delete the old delete icon; icon=NULL; /// Update if (size<=16) { icon = new FXPNGIcon(getApp(),gogglesmm_16_png,0,opaque ? IMAGE_OPAQUE : 0); icon->setVisual(getVisual()); if (size!=16) icon->scale(size,size,1); } else { icon = new FXPNGIcon(getApp(),gogglesmm_32_png,0,opaque ? IMAGE_OPAQUE : 0); icon->setVisual(getVisual()); if (size!=32) icon->scale(size,size,1); } icon->blend(GMPlayerManager::instance()->getPreferences().gui_tray_color); icon->create(); // Mark Dirty update(); } } FXbool GMTrayIcon::findSystemTray() { FXString systemtray = GMStringFormat("_NET_SYSTEM_TRAY_S%d",DefaultScreen((Display*)getApp()->getDisplay())); Atom xtrayselection = XInternAtom((Display*)getApp()->getDisplay(),systemtray.text(),0); if (xtrayselection!=None) { xtraywindow = (FXID)XGetSelectionOwner((Display*)getApp()->getDisplay(),xtrayselection); } return (xtraywindow!=0); } void GMTrayIcon::requestDock() { if (xid && xtraywindow) { XEvent ev; memset(&ev,0,sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = xtraywindow; ev.xclient.message_type = xtrayopcode; ev.xclient.format = 32; ev.xclient.data.l[0] = CurrentTime; ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK; ev.xclient.data.l[2] = xid; XSendEvent((Display*)getApp()->getDisplay(),xtraywindow,False,NoEventMask,&ev); XSync((Display*)getApp()->getDisplay(),0); } } FXuint GMTrayIcon::getTrayOrientation(){ if (xtrayorientation || xtrayxfceorientation) { FXuint orientation; Atom returntype; int returnformat; unsigned long nitems; unsigned long nbytes; long * bytes=NULL; if (xtrayorientation && (XGetWindowProperty((Display*)getApp()->getDisplay(),(Atom)xtraywindow,(Atom)xtrayorientation,0,2,False,XA_CARDINAL,&returntype,&returnformat,&nitems,&nbytes,(unsigned char**)(void*)&bytes)==Success) && returntype==XA_CARDINAL){ orientation=*(long*)bytes; XFree(bytes); return orientation; } if (bytes!=NULL) { XFree(bytes); bytes=NULL; } if (xtrayxfceorientation && (XGetWindowProperty((Display*)getApp()->getDisplay(),(Atom)xtraywindow,(Atom)xtrayxfceorientation,0,2,False,XA_CARDINAL,&returntype,&returnformat,&nitems,&nbytes,(unsigned char**)(void*)&bytes)==Success) && returntype==XA_CARDINAL){ orientation=*(long*)bytes; XFree(bytes); return orientation; } if (bytes!=NULL) { XFree(bytes); bytes=NULL; } } return SYSTEM_TRAY_UNKNOWN; } FXuint GMTrayIcon::getTrayVisual(){ if (xtrayvisual) { FXuint visualid; Atom returntype; int returnformat; unsigned long nitems; unsigned long nbytes; long * bytes=NULL; if (xtrayvisual && (XGetWindowProperty((Display*)getApp()->getDisplay(),xtraywindow,xtrayvisual,0,2,False,XA_VISUALID,&returntype,&returnformat,&nitems,&nbytes,(unsigned char**)(void*)&bytes)==Success) && returntype==XA_VISUALID){ visualid=*(long*)bytes; //fxmessage("visualid %d\n",visualid); XFree(bytes); return visualid; } if (bytes!=NULL) { XFree(bytes); bytes=NULL; } } return 0; } void GMTrayIcon::create(){ xtrayopcode = (FXID)XInternAtom((Display*)getApp()->getDisplay(),"_NET_SYSTEM_TRAY_OPCODE",0); xtrayorientation = (FXID)XInternAtom((Display*)getApp()->getDisplay(),"_NET_SYSTEM_TRAY_ORIENTATION",0); xtrayxfceorientation = (FXID)XInternAtom((Display*)getApp()->getDisplay(),"_NET_XFCE_TRAY_MANAGER_ORIENTATION",0); xtrayvisual = (FXID)XInternAtom((Display*)getApp()->getDisplay(),"_NET_SYSTEM_TRAY_VISUAL",0); GMPlug::create(); if (xid) { /// Set the size hints... XSizeHints size; size.flags=PMinSize|PMaxSize|PBaseSize|PAspect; size.x=0; size.y=0; size.width=0; size.height=0; size.width_inc=0; size.height_inc=0; size.min_aspect.x=1; size.min_aspect.y=1; size.max_aspect.x=1; size.max_aspect.y=1; size.win_gravity=0; size.win_gravity=0; size.min_width=8; size.min_height=8; size.max_width=64; size.max_height=64; size.base_width=32; size.base_height=32; XSetWMNormalHints((Display*)getApp()->getDisplay(),xid,&size); } } FXbool GMTrayIcon::dock() { if (findSystemTray()){ FXuint id = getTrayVisual(); if (id) { if (id!=XVisualIDFromVisual((Visual*)getVisual()->getVisual())) opaque=true; else opaque=false; } if (!opaque) { /// Don't draw the background XSetWindowAttributes sattr; sattr.background_pixmap = ParentRelative; XChangeWindowAttributes((Display*)getApp()->getDisplay(),xid,CWBackPixmap,&sattr); } requestDock(); return true; } return false; } long GMTrayIcon::onConfigure(FXObject*,FXSelector,void*ptr){ FXEvent * event = (FXEvent*)ptr; // GMPlug::onConfigure(sender,sel,ptr); //fxmessage("GMTrayIcon::onConfigure %d %d\n",event->rect.w,event->rect.h); FXuint orientation = getTrayOrientation(); FXint size=0; switch(orientation){ case SYSTEM_TRAY_HORIZONTAL: size=event->rect.h; break; case SYSTEM_TRAY_VERTICAL : size=event->rect.w; break; default : size=FXMAX(event->rect.h,event->rect.w); break; }; resize(size,size); XSizeHints hint; hint.flags=PMinSize|PMaxSize|PBaseSize; hint.min_width = hint.max_width = hint.base_width = size; hint.min_height = hint.max_height = hint.base_height = size; XSetWMNormalHints((Display*)getApp()->getDisplay(),xid,&hint); if (icon && icon->getWidth()!=size) { delete icon; icon=NULL; } if (icon==NULL) { if (size<=16) { icon = new FXPNGIcon(getApp(),gogglesmm_16_png,0,opaque ? IMAGE_OPAQUE : 0); icon->setVisual(getVisual()); if (size!=16) icon->scale(size,size,1); } else { icon = new FXPNGIcon(getApp(),gogglesmm_32_png,0,opaque ? IMAGE_OPAQUE : 0); icon->setVisual(getVisual()); if (size!=32) icon->scale(size,size,1); } icon->blend(GMPlayerManager::instance()->getPreferences().gui_tray_color); icon->create(); } return 1; } long GMTrayIcon::onRightBtnRelease(FXObject*,FXSelector,void*ptr){ FXEvent * event=(FXEvent*)ptr; if (event->moved) return 0; GMMenuPane pane(this,POPUP_SHRINKWRAP); new GMMenuCommand(&pane,pane.tr("Play"),GMIconTheme::instance()->icon_play,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_PLAYPAUSEMENU); new GMMenuCommand(&pane,pane.tr("Stop"),GMIconTheme::instance()->icon_stop,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_STOP); new GMMenuCommand(&pane,pane.tr("Previous Track"),GMIconTheme::instance()->icon_prev,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_PREV); new GMMenuCommand(&pane,pane.tr("Next Track"),GMIconTheme::instance()->icon_next,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_NEXT); new FXMenuSeparator(&pane); new GMMenuCommand(&pane,tr("Quit"),GMIconTheme::instance()->icon_exit,GMPlayerManager::instance()->getMainWindow(),GMWindow::ID_QUIT); gm_set_window_cursor(&pane,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); pane.create(); pane.forceRefresh(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+1,event->root_y+1); getApp()->runModalWhileShown(&pane); return 1; } long GMTrayIcon::onLeftBtnPress(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->cmd_toggle_shown(); return 1; } long GMTrayIcon::onMiddleBtnPress(FXObject*,FXSelector,void*){ GMPlayerManager * p = GMPlayerManager::instance(); if (p->can_pause()) p->pause(); else if (p->can_unpause()) p->unpause(); else if (p->can_play()) p->play(); return 1; } long GMTrayIcon::onMouseWheel(FXObject*sender,FXSelector sel,void*ptr){ GMPlayerManager::instance()->getMainWindow()->handle(sender,sel,ptr); return 1; } long GMTrayIcon::onQueryTip(FXObject*sender,FXSelector sel,void* ptr){ if(FXTopWindow::onQueryTip(sender,sel,ptr)) return 1; if((flags&FLAG_TIP) && !tip.empty() && !grabbed() ){ sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&tip); return 1; } return 0; } long GMTrayIcon::onPaint(FXObject*,FXSelector,void*){ if (icon) { FXDCWindow dc(this); dc.drawIcon(icon,0,0); } return 1; } gogglesmm-0.12.7/src/mpris_tracklist.xml0000644000175000001440000000175111435112736017037 0ustar sxjusers gogglesmm-0.12.7/src/GMEQDialog.h0000644000175000001440000000537611525430601015126 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMEQDIALOG_H #define GMEQDIALOG_H class GMEQPreset { public: FXString name; GMEQBands bands; }; class GMEQDialog : public FXDialogBox { FXDECLARE(GMEQDialog) static GMEQDialog * myself; protected: FXFontPtr font_small; protected: FXArray presets; FXRealSlider * eqslider[10]; GMListBox * presetlist; protected: GMEQDialog(){} private: GMEQDialog(const GMEQDialog&); GMEQDialog &operator=(const GMEQDialog&); protected: void listPresets(); public: static GMEQDialog * instance(); public: enum { ID_PRESET_EQ=FXDialogBox::ID_LAST, ID_SAVE, ID_RESET, ID_DELETE, ID_EQ_30HZ, ID_EQ_60HZ, ID_EQ_125HZ, ID_EQ_250HZ, ID_EQ_500HZ, ID_EQ_1000HZ, ID_EQ_2000HZ, ID_EQ_4000HZ, ID_EQ_8000HZ, ID_EQ_16000HZ }; public: long onCmdEQ(FXObject*,FXSelector,void*); long onUpdEQ(FXObject*,FXSelector,void*); long onCmdPresetEQ(FXObject*,FXSelector,void*); long onCmdReset(FXObject*,FXSelector,void*); long onCmdSave(FXObject*,FXSelector,void*); long onCmdDelete(FXObject*,FXSelector,void*); long onUpdReset(FXObject*,FXSelector,void*); long onUpdSave(FXObject*,FXSelector,void*); long onUpdDelete(FXObject*,FXSelector,void*); public: GMEQDialog(FXWindow * p); virtual void hide(); virtual ~GMEQDialog(); }; #endif gogglesmm-0.12.7/src/GMMessageChannel.h0000644000175000001440000000750711525430601016354 0ustar sxjusers/******************************************************************************** * * * I n t e r - T h r e a d M e s s a g i n g C h a n n e l * * * ********************************************************************************* * Copyright (C) 2006-2011 by Jeroen van der Zijp. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see * ********************************************************************************* * $Id: FXMessageChannel.h,v 1.6 2007/07/09 16:02:46 fox Exp $ * ********************************************************************************/ #ifndef GMMESSAGECHANNEL_H #define GMMESSAGECHANNEL_H #ifndef HAVE_FOX16 #error Only needed for FOX 1.6 #endif #ifndef FXOBJECT_H #include "FXObject.h" #endif namespace FX { class FXApp; /** * FXMessageChannel manages a messaging channel between a worker thread and the main * user-interface thread. * When an FXMessageChannel is constructed, it automatically calls addInput() function to * register itself as the message handler for the SEL_IO_READ message from FXApp. * Likewise, when FXMessageChannel is destroyed, it calls removeInput() to remove itself * as the message handler for the SEL_IO_READ message from FXApp. * When a worker thread calls the message() API, the target and message, as well * as optional message data, are written into the message channel. * The main user-interface thread is awakened and subsequently dispatches to the * onMessage handler of FXMessageChannel, which reads the target, selector, and optional * message data from the channel and then dispatches to this target using the given * selector. * Thus, FXMessageChannel provides a worker thread with a way to asynchronously invoke * any message handler in the context of the main user-interface thread. * If the size of the optional data is zero, the message handler will be passed a * NULL pointer. */ class FXMessageChannel : public FXObject { FXDECLARE(FXMessageChannel) private: FXApp *app; private: FXInputHandle h[3]; FXMutex m; protected: FXMessageChannel(); private: FXMessageChannel(const FXMessageChannel&); FXMessageChannel& operator=(const FXMessageChannel&); public: enum{ ID_IO_READ=1, ID_LAST }; public: long onMessage(FXObject*,FXSelector,void*); public: /// Initialize message channel FXMessageChannel(FXApp* a); /// Get application pointer FXApp* getApp() const { return app; } /// Send a message msg comprising of FXSEL(type,id) to a target tgt, and pass optional data of size bytes FXbool message(FXObject* tgt,FXSelector msg,const void* data=NULL,FXint size=0); /// Clean up message channel virtual ~FXMessageChannel(); }; } #endif gogglesmm-0.12.7/src/GMTrackDatabase.cpp0000644000175000001440000023623611526346513016537 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "GMTrackDatabase.h" #include "GMTag.h" #include "GMTrackList.h" #include "GMList.h" #include "GMSource.h" /// For listing default genres #include #define GOGGLESMM_DATABASE_SCHEMA_VERSION 2009 /* ***************************************************** Goggles Music Manager Database Schema v2009 ***************************************************** TABLE tracks id INTEGER NOT NULL * path INTEGER mrl TEXT title TEXT NOT NULL time INTEGER no INTEGER year INTEGER playcount INTEGER playdate INTEGER importdate INTEGER album INTEGER NOT NULL genre INTEGER rating INTEGER artist INTEGER NOT NULL replay_gain REAL replay_peak REAL TABLE genres id INTEGER NOT NULL * name TEXT NOT NULL UNIQUE TABLE artists id INTEGER NOT NULL * name TEXT NOT NULL UNIQUE TABLE albums id INTEGER NOT NULL * name TEXT artists INTEGER NOT NULL year INTEGER NOT NULL replay_gain REAL replay_peak REAL TABLE playlists id INTEGER NOT NULL * name TEXT TABLE playlist_tracks playlist INTEGER track INTEGER queue INTEGER */ static FXString last_dir; static FXint last_path=-1; const FXchar create_streams[]="CREATE TABLE streams ( id INTEGER NOT NULL, " "url TEXT, " "description TEXT, " "genre INTEGER, " "bitrate INTEGER, " "rating INTEGER, " "PRIMARY KEY (id) );"; const FXchar create_tracks[]="CREATE TABLE tracks ( id INTEGER NOT NULL, " "path INTEGER, " "mrl TEXT, " "title TEXT NOT NULL, " "time INTEGER, " "no INTEGER, " "year INTEGER, " "playcount INTEGER, " "playdate INTEGER, " "importdate INTEGER, " "album INTEGER NOT NULL, " "genre INTEGER, " "rating INTEGER, " "artist INTEGER NOT NULL, " "replay_gain REAL, " "replay_peak REAL, " "PRIMARY KEY (id) );"; const FXchar create_genres[]="CREATE TABLE genres ( id INTEGER NOT NULL, name TEXT NOT NULL UNIQUE, PRIMARY KEY (id) );"; const FXchar create_albums[]="CREATE TABLE albums ( id INTEGER NOT NULL, " "name TEXT NOT NULL, " "artist INTEGER NOT NULL, " "year INTEGER, " "replay_gain REAL, " "replay_peak REAL, " "PRIMARY KEY (id) );"; const FXchar create_artists[]="CREATE TABLE artists ( id INTEGER NOT NULL, name TEXT NOT NULL UNIQUE, PRIMARY KEY (id) );"; const FXchar create_playlists[]="CREATE TABLE playlists ( id INTEGER NOT NULL, name TEXT, PRIMARY KEY (id) );"; const FXchar create_playlist_tracks[]="CREATE TABLE playlist_tracks ( playlist INTEGER NOT NULL, track INTEGER NOT NULL, queue INTEGER );"; const FXchar create_directories[]="CREATE TABLE directories ( id INTEGER PRIMARY KEY,parent INTEGER,name TEXT,path TEXT);"; const FXchar create_trigger_diradd[]="CREATE TRIGGER directories_insert AFTER INSERT ON directories " "BEGIN " "UPDATE directories SET path = " "CASE WHEN parent ISNULL THEN '/' " "ELSE (SELECT path FROM directories WHERE id = new.parent) || parent || '/' " "END " "WHERE id = new.id; " "END;"; // Recursive Trigger not supported by SQLite //const FXchar create_trigger_dirdel[]="CREATE TRIGGER directories_delete AFTER DELETE ON directories " // "BEGIN " // "DELETE FROM directories WHERE id IN " // "(SELECT id FROM directories WHERE path LIKE old.path || old.id || '/%' ); " // "END;"; GMTrackDatabase::GMTrackDatabase() { } GMTrackDatabase::~GMTrackDatabase() { } FXbool GMTrackDatabase::clearTracks(FXbool removeplaylists){ if (!db.execute("DELETE FROM tracks;")) return false; if (!db.execute("DELETE FROM artists")) return false; if (!db.execute("DELETE FROM albums;")) return false; if (!db.execute("DELETE FROM playlist_tracks;")) return false; if (removeplaylists) { if (!db.execute("DELETE FROM playlists;")) return false; } if (!db.execute("DELETE FROM directories;")) return false; last_path=-1; if (!db.execute("DELETE FROM genres WHERE id NOT IN (SELECT DISTINCT(genre) FROM tracks) AND id NOT IN (SELECT DISTINCT(genre) FROM streams);")) return false; return true; } void GMTrackDatabase::clear(){ db.clearTables(); } FXbool GMTrackDatabase::init(const FXString & database,FXbool checkversion) { if (!db.open(database)) goto error; if (checkversion && db.getVersion()>GOGGLESMM_DATABASE_SCHEMA_VERSION) { if (FXMessageBox::question(FXApp::instance(),MBOX_OK_CANCEL,fxtr("Database Error"),fxtr("An incompatible (future) version of the database was found.\nThis usually happens when you try to downgrade to a older version of GMM\nPress OK to continue and reset the database (all information will be lost!).\nPress Cancel to quit now and leave the database as is."))==MBOX_CLICKED_CANCEL) return false; } if (!setup_tables()) goto error; if (!setup_queries()) goto error; return true; error: FXMessageBox::error(FXApp::instance(),MBOX_OK,fxtr("Fatal Error"),fxtr("Goggles Music Manager was unable to open the database.\nThe database may have been corrupted. Please remove ~/.goggles/goggles.db to try again.\nif the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmm")); return false; } void GMTrackDatabase::setup_insert_queries() { } void GMTrackDatabase::clear_insert_queries() { } void GMTrackDatabase::beginDelete() { delete_artist.compile(db,"DELETE FROM artists WHERE id == ?;"); delete_genre.compile(db,"DELETE FROM genres WHERE id == ?;"); delete_album.compile(db,"DELETE FROM albums WHERE id == ?;"); delete_track.compile(db,"DELETE FROM tracks WHERE id == ?;"); delete_track_artist.compile(db,"DELETE FROM tracks WHERE artist == ? OR album IN ( SELECT id FROM albums WHERE artist == ?) ;"); delete_track_album.compile(db,"DELETE FROM tracks WHERE album == ?;"); delete_albums_artist.compile(db,"DELETE FROM albums WHERE artist == ?;"); delete_track_from_playlist.compile(db,"DELETE FROM playlist_tracks WHERE track == ? AND playlist == ?;"); delete_track_from_playlists.compile(db,"DELETE FROM playlist_tracks WHERE track == ?;"); delete_artist_from_playlists.compile(db,"DELETE FROM playlist_tracks WHERE track IN ( SELECT id FROM tracks WHERE artist == ? OR album IN (SELECT album FROM albums WHERE artist == ?));"); delete_album_from_playlists.compile(db,"DELETE FROM playlist_tracks WHERE track IN (SELECT id FROM tracks WHERE album == ?);"); query_track_no.compile(db,"SELECT no FROM tracks WHERE id == ?;"); } void GMTrackDatabase::endDelete(FXbool vac){ if (vac) vacuum(); delete_artist.clear(); delete_genre.clear(); delete_track.clear(); delete_track_artist.clear(); delete_track_album.clear(); delete_album.clear(); delete_albums_artist.clear(); delete_artist_from_playlists.clear(); delete_album_from_playlists.clear(); delete_track_from_playlist.clear(); delete_track_from_playlists.clear(); query_track_no.clear(); } void GMTrackDatabase::beginEdit() { update_track_genre_id.compile(db,"UPDATE tracks SET genre = ? WHERE id == ?;"); update_mrl.compile(db,"UPDATE tracks SET path = ?, mrl = ? WHERE id == ?;"); update_artist_album_id.compile(db,"UPDATE albums SET artist = ? WHERE id == ?;"); update_track_title.compile(db,"UPDATE tracks SET title = ? WHERE id == ?;"); update_track_album_id.compile(db,"UPDATE tracks SET album = ? WHERE id == ?;"); update_track_genre.compile(db,"UPDATE tracks SET genre = ? WHERE genre == ?;"); update_track_artist.compile(db,"UPDATE tracks SET artist = ? WHERE id == ?;"); update_track_no.compile(db,"UPDATE tracks SET no = ? WHERE id == ?;"); update_track_disc.compile(db,"UPDATE tracks SET no = ((no&65535)|(?<<16)) WHERE id == ?;"); update_track_track.compile(db,"UPDATE tracks SET no = ((no&1048560)|?) WHERE id == ?;"); update_track_importdate.compile(db,"UPDATE tracks SET importdate = ? WHERE id == ?;"); update_track_year.compile(db,"UPDATE tracks SET year = ? WHERE id == ?;"); update_track.compile(db,"UPDATE tracks SET title = ?, time = ?, no = ?, year = ?, album = ?, genre = ?, artist = ?, replay_gain = ?, replay_peak = ?, importdate = ? WHERE id == ?;"); update_album.compile(db,"UPDATE albums SET year = ?, replay_gain = ?, replay_peak = ? WHERE id == ?;"); query_track_no.compile(db,"SELECT no FROM tracks WHERE id == ?;"); query_album_existing.compile(db,"SELECT id FROM albums WHERE artist == ? AND name == (SELECT albums.name FROM albums WHERE albums.id == (SELECT album FROM tracks WHERE id == ? ));"); insert_album_existing.compile(db,"INSERT INTO albums ( name, artist, year, replay_gain, replay_peak) SELECT ?, ?, year,replay_gain,replay_peak FROM albums WHERE id == (SELECT album FROM tracks WHERE id == ? ) ;"); insert_album_existing_name.compile(db,"INSERT INTO albums ( name, artist, year, replay_gain, replay_peak) SELECT name, ?, year,replay_gain,replay_peak FROM albums WHERE id == (SELECT album FROM tracks WHERE id == ? ) ;"); query_artist_album.compile(db,"SELECT artist FROM albums WHERE id == (SELECT album FROM tracks WHERE id == ?);"); } void GMTrackDatabase::endEdit(FXbool vac){ if (vac) vacuum(); update_track_genre_id.clear(); update_mrl.clear(); update_artist_album_id.clear(); update_track_title.clear(); update_track_album_id.clear(); update_track_genre.clear(); update_track_artist.clear(); update_track_no.clear(); update_track_disc.clear(); update_track_track.clear(); update_track_year.clear(); update_track.clear(); update_album.clear(); update_track_importdate.clear(); query_track_no.clear(); query_album_existing.clear(); insert_album_existing.clear(); insert_album_existing_name.clear(); query_artist_album.clear(); } #include "GMPlayerManager.h" #ifdef DEBUG namespace FX { extern FXlong fxgetticks(); } static FXlong total_ticks = 0; static FXlong total_has_ticks = 0; #endif FXbool GMTrackDatabase::hasTrack(const FXString & dir,const FXString & filename,FXint & trackid) { FXint pathid=-1; trackid=-1; #ifdef DEBUG FXlong start=fxgetticks(); #endif if (last_dir==dir) { if (last_path!=-1) { query_filename.setParameter(0,last_path); query_filename.setParameter(1,filename); query_filename.execute(); query_filename.getResult(0,trackid); query_filename.reset(); } } else if (findPath(dir,pathid)){ query_filename.setParameter(0,pathid); query_filename.setParameter(1,filename); query_filename.execute(); query_filename.getResult(0,trackid); query_filename.reset(); last_path=pathid; last_dir=dir; } else { last_path=-1; last_dir=dir; } #ifdef DEBUG FXlong end=fxgetticks(); total_has_ticks+=(end-start); #endif if (trackid==-1) { return false; } return true; } FXbool GMTrackDatabase::hasTrack(const FXString & filename,FXint & trackid) { return hasTrack(FXPath::directory(filename),FXPath::name(filename),trackid); } FXbool GMTrackDatabase::findPath(const FXString & path,FXint & id) { if (!FXPath::isTopDirectory(path)) { FXString parent = FXPath::upLevel(path); if (!findPath(parent,id)) return false; FXString name = FXPath::name(path); FXint nid = -1; query_path_component.setParameter(0,id); query_path_component.setParameter(1,name); query_path_component.execute(); query_path_component.getResult(0,nid); query_path_component.reset(); if (nid==-1) return false; id=nid; } else { id=-1; query_root_component.setParameter(0,path); query_root_component.execute(); query_root_component.getResult(0,id); query_root_component.reset(); if (id==-1) return false; } return true; } void GMTrackDatabase::addPath(const FXString & path,FXint & id) { if (!FXPath::isTopDirectory(path)) { FXString parent = FXPath::upLevel(path); FXString name = FXPath::name(path); FXint nid = -1; addPath(parent,id); query_path_component.setParameter(0,id); query_path_component.setParameter(1,name); query_path_component.execute(); query_path_component.getResult(0,nid); query_path_component.reset(); if (nid==-1) { insert_path_component.setParameter(0,id); insert_path_component.setParameter(1,name); insert_path_component.execute(); insert_path_component.reset(); id = db.lastInsertRow(); } else { id = nid; } } else { id=-1; query_root_component.setParameter(0,path); query_root_component.execute(); query_root_component.getResult(0,id); query_root_component.reset(); if (id==-1) { insert_root_component.setParameter(0,path); insert_root_component.execute(); insert_root_component.reset(); id = db.lastInsertRow(); } } } FXbool GMTrackDatabase::insertTrack(const GMTrack & track,FXint & result){ FXint artist=-1; FXint album=-1; FXint genre=0; FXint path=-1; result=0; #ifdef DEBUG FXlong start = fxgetticks(); #endif if (!queryArtist(artist,track.album_artist,true)) return FALSE; if (!queryAlbum(album,track.album,artist,track.year,track.album_gain,track.album_peak,true)) return FALSE; if (!track.genre.empty() && !queryGenre(genre,track.genre,true)) return FALSE; /// Insert Track Artist if needed if (!track.artist.empty() && track.artist!=track.album_artist && !queryArtist(artist,track.artist,true)) return false; static int cached=0; static int newentry=0; FXString dir=FXPath::directory(track.mrl); if (last_path>=0 && last_dir==dir){ path=last_path; cached++; } else { addPath(dir,path); last_path=path; last_dir=dir; newentry++; } /// Needed for hasTrack try { insert_track.setParameter(0,path); if (path>=0) insert_track.setParameter(1,FXPath::name(track.mrl)); else insert_track.setParameter(1,track.mrl); insert_track.setParameter(2,track.title); insert_track.setParameter(3,track.time); insert_track.setParameter(4,track.no); insert_track.setParameter(5,track.year); insert_track.setParameter(6,FXThread::time()); insert_track.setParameter(7,album); insert_track.setParameter(8,genre); insert_track.setParameter(9,artist); insert_track.setParameter(10,track.track_gain); insert_track.setParameter(11,track.track_peak); insert_track.execute(); result = db.lastInsertRow(); // if (result>0 && trackdict_updated) { // trackdict.insert(track.mrl.text(),(void*)(FXival)result); // } insert_track.reset(); } catch (FXExecuteException & e){ fxmessage("Exception: %s\n",e.what()); result=0; return FALSE; } #ifdef DEBUG FXlong end = fxgetticks(); total_ticks += (end-start); fxmessage("insert: %ld\n",end-start); #endif return true; } FXbool GMTrackDatabase::updateTrack(FXint id,const GMTrack & track){ FXint album=-1; FXint genre=-1; FXint artist=-1; FXuint no=track.no; if (!queryArtist(artist,track.album_artist,true)) return FALSE; if (!updateAlbum(album,track,artist)) return false; // if (!queryAlbum(album,track.album,artist,track.year,track.album_gain,track.album_peak,true)) return FALSE; if (!track.genre.empty() && !queryGenre(genre,track.genre,true)) return FALSE; if (!track.artist.empty() && track.artist!=track.album_artist && !queryArtist(artist,track.artist,true)) return false; try { if (track.no==0) { query_track_no.setParameter(0,id); query_track_no.execute(); query_track_no.getResult(0,no); query_track_no.reset(); } update_track.setParameter(0,track.title); update_track.setParameter(1,track.time); update_track.setParameter(2,no); update_track.setParameter(3,track.year); update_track.setParameter(4,album); update_track.setParameter(5,genre); update_track.setParameter(6,artist); update_track.setParameter(7,track.track_gain); update_track.setParameter(8,track.track_peak); update_track.setParameter(9,FXThread::time()); update_track.setParameter(10,id); update_track.execute(); update_track.reset(); } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::insertStream(const FXString & url,const FXString & description,const FXString & genre){ FXString query; FXint genreid=0; if (!genre.empty() && !queryGenre(genreid,genre,true)) return false; query.format("INSERT INTO streams VALUES (NULL,\"%s\",\"%s\",%d,0,0);",url.text(),description.text(),genreid); return db.execute(query); } /// Insert Playlist into database FXbool GMTrackDatabase::insertPlaylist(const FXString & name,FXint & id) { try { GMQuery query(&db,"INSERT INTO playlists VALUES ( NULL, ? );"); query.setParameter(0,name); query.execute(); id = db.lastInsertRow(); query.reset(); } catch (FXCompileException &){ return false; } catch (FXExecuteException &){ return false; } return true; } /// Insert Track in Playlist FXbool GMTrackDatabase::insertTrackInPlaylist(FXint playlist,FXint & track) { FXint queue=0; try { GMQuery queu_query(&db,"SELECT MAX(queue) FROM playlist_tracks WHERE playlist == ?;"); queu_query.setParameter(0,playlist); queu_query.execute(); queu_query.getResult(0,queue); queu_query.reset(); // Increment queue++; GMQuery insert_query(&db,"INSERT INTO playlist_tracks VALUES ( ? , ? , ?);"); insert_query.setParameter(0,playlist); insert_query.setParameter(1,track); insert_query.setParameter(2,queue); insert_query.execute(); } catch (FXCompileException & e){ fxmessage("Compile Exception: %s\n",e.what()); return false; } catch (FXExecuteException & e){ fxmessage("Execute Exception: %s\n",e.what()); return false; } return true; } /// Insert Track in Playlist FXbool GMTrackDatabase::insertTrackInPlaylist(FXint playlist,FXIntList & tracks) { FXint queue=0; try { query_playlist_queue.setParameter(0,playlist); query_playlist_queue.execute(); query_playlist_queue.getResult(0,queue); query_playlist_queue.reset(); // Increment queue++; #ifdef DEBUG FXlong start = fxgetticks(); #endif db.begin(); for (int i=0;i=0) update_mrl.setParameter(1,FXPath::name(filename)); else update_mrl.setParameter(1,filename); update_mrl.setParameter(2,id); update_mrl.execute(); update_mrl.reset(); } catch (FXExecuteException &){ } } FXString GMTrackDatabase::getTrackFilename(FXint id){ FXString filename; FXString path; FXint pathid; try { query_track_filename.setParameter(0,id); query_track_filename.execute(); query_track_filename.getResult(0,filename); query_track_filename.getResult(1,pathid); query_track_filename.reset(); query_path.setParameter(0,pathid); while(query_path.execute()) { if (!path.empty() && path!="/") path+=PATHSEPSTRING; path+=query_path.getResult(0); } query_path.reset(); } catch (FXExecuteException &){ return FXString::null; } if (path.empty()) return filename; else return path + PATHSEPSTRING + filename; } /// Return list of filenames void GMTrackDatabase::getTrackFilenames(const FXIntList & tracks,FXStringList & filenames){ filenames.no(tracks.no()); for (FXint i=0;i0); } FXbool GMTrackDatabase::getAlbumTrack(FXint id,FXString & path) { FXString filename; FXint pathid; try { query_track_filename_by_album.setParameter(0,id); query_track_filename_by_album.execute(); query_track_filename_by_album.getResult(0,filename); query_track_filename_by_album.getResult(1,pathid); query_track_filename_by_album.reset(); query_path.setParameter(0,pathid); while(query_path.execute()) { if (!path.empty() && path!="/") path+=PATHSEPSTRING; path+=query_path.getResult(0); } query_path.reset(); } catch (FXExecuteException &){ return false; } if (path.empty()) path=filename; else path+=PATHSEPSTRING+filename; return true; } FXint GMTrackDatabase::getAlbumPath(FXint id) { FXint path; try { GMQuery query(&db,"SELECT path FROM tracks WHERE album == ? LIMIT(1);"); query.setParameter(0,id); query.execute(); query.getResult(0,path); query.reset(); } catch (FXCompileException &){ return -1; } catch (FXExecuteException &){ return -1; } return path; } FXString GMTrackDatabase::getPathName(FXint id) { FXString path; try { query_path.setParameter(0,id); while(query_path.execute()) { if (!path.empty() && path!="/") path+=PATHSEPSTRING; path+=query_path.getResult(0); } query_path.reset(); } catch (FXExecuteException &){ return FXString::null; } return path; } FXString GMTrackDatabase::getAlbumName(FXint id) { FXString result; queryAlbum(result,id); return result; } FXString GMTrackDatabase::getAlbumArtist(FXint id) { FXString result; queryArtist(result,id); return result; } FXString GMTrackDatabase::getArtistName(FXint id){ FXString result; try { query_artist_name.setParameter(0,id); query_artist_name.execute(); result = query_artist_name.getResult(0); query_artist_name.reset(); } catch (FXExecuteException &){ return FXString::null; } return result; } FXString GMTrackDatabase::getGenreName(FXint id){ FXString name; try { GMQuery query(&db,"SELECT name FROM genres WHERE id == ?;"); query.setParameter(0,id); query.execute(); query.getResult(0,name); query.reset(); } catch (FXCompileException &){ return FXString::null; } catch (FXExecuteException &){ return FXString::null; } return name; } FXint GMTrackDatabase::getTrackAlbum(FXint id){ FXint result; FXint year; queryAlbum(result,year,id); return result; } /* FXint GMTrackDatabase::hasTrack(const FXString & mrl){ FXString filename; FXint id; if (!trackdict_updated) { trackdict.clear(); try { while(list_all_tracks.execute()){ list_all_tracks.getResult(0,id); list_all_tracks.getResult(1,filename); trackdict.insert(filename.text(),(void*)(FXival)id); } list_all_tracks.reset(); } catch (FXExecuteException & e){ return 0; } trackdict_updated=true; } void * data = trackdict.find(mrl.text()); if (data==NULL) return 0; else return (FXint)(FXival) data; } */ FXbool GMTrackDatabase::getStream(FXint id,GMStream & stream){ FXString query; query.format("SELECT url,description,genres.name,bitrate FROM streams, genres WHERE genres.id == streams.genre AND streams.id == %d;",id); GMQuery get_stream; try { get_stream.compile(db,query); get_stream.execute(); stream.url=get_stream.getResult(0); stream.description=get_stream.getResult(1); stream.genre=get_stream.getResult(2); get_stream.getResult(3,stream.bitrate); get_stream.reset(); } catch (FXCompileException &){ return false; } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::getTrack(FXint id,GMTrack & track){ FXString path,filename,number; FXint pathid; try { query_track.setParameter(0,id); query_track.execute(); query_track.getResult(0,pathid); query_track.getResult(1,filename); query_track.getResult(2,track.album); query_track.getResult(3,track.album_artist); query_track.getResult(4,track.artist); query_track.getResult(5,track.genre); query_track.getResult(6,track.title); query_track.getResult(7,track.time); query_track.getResult(8,track.no); query_track.getResult(9,track.year); query_track.getResult(10,track.track_gain); query_track.getResult(11,track.track_peak); query_track.getResult(12,track.album_gain); query_track.getResult(13,track.album_peak); query_track.reset(); if (pathid>=0) { query_path.setParameter(0,pathid); while(query_path.execute()) { if (!path.empty() && path!="/") path+=PATHSEPSTRING; path+=query_path.getResult(0); } query_path.reset(); } if (!path.empty()) track.mrl = path + PATHSEPSTRING + filename; else track.mrl = filename; } catch (FXExecuteException &){ return FALSE; } return true; } FXbool GMTrackDatabase::getTrackAssociation(FXint id,FXint & artist,FXint & album){ try { query_album_artists.setParameter(0,id); query_album_artists.execute(); query_album_artists.getResult(0,artist); query_album_artists.getResult(1,album); query_album_artists.reset(); } catch (FXCompileException &){ return false; } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::removeGenre(FXint id,FXbool update_tracks) { GMQuery remove_genre; GMQuery remove_tracks; GMQuery remove_albums; GMQuery remove_artist; try { db.begin(); remove_genre.compile((GMDatabase*)this,"DELETE FROM genres WHERE id == ?;"); remove_tracks.compile((GMDatabase*)this,"DELETE FROM tracks WHERE genre == ?;"); remove_albums.compile((GMDatabase*)this,"DELETE FROM albums WHERE id NOT IN ( SELECT album FROM tracks);"); remove_artist.compile((GMDatabase*)this,"DELETE FROM artists WHERE id NOT IN ( SELECT DISTINCT(artist) FROM albums ) AND id NOT IN ( SELECT DISTINCT(artist) FROM tracks ) ; "); remove_genre.setParameter(0,id); remove_genre.perform(); if (update_tracks) { remove_tracks.setParameter(0,id); remove_tracks.perform(); remove_albums.perform(); remove_artist.perform(); remove_tracks.reset(); remove_albums.reset(); remove_artist.reset(); } remove_genre.reset(); db.commit(); } catch (FXCompileException &){ db.rollback(); return false; } catch (FXExecuteException &){ db.rollback(); return false; } return true; } FXbool GMTrackDatabase::removeArtist(FXint artist) { try { db.begin(); /// Remove tracks from artist from playlists. delete_artist_from_playlists.setParameter(0,artist); delete_artist_from_playlists.setParameter(1,artist); delete_artist_from_playlists.execute(); delete_artist_from_playlists.reset(); /// Remove Tracks delete_track_artist.setParameter(0,artist); delete_track_artist.setParameter(1,artist); delete_track_artist.execute(); delete_track_artist.reset(); /// Remove Album Entries delete_albums_artist.setParameter(0,artist); delete_albums_artist.execute(); delete_albums_artist.reset(); /// Remove Artist itself delete_artist.setParameter(0,artist); delete_artist.execute(); delete_artist.reset(); db.commit(); } catch (FXExecuteException &){ db.rollback(); return false; } return true; } FXbool GMTrackDatabase::removeAlbum(FXint album) { try { db.begin(); delete_album_from_playlists.setParameter(0,album); delete_album_from_playlists.execute(); delete_album_from_playlists.reset(); delete_track_album.setParameter(0,album); delete_track_album.execute(); delete_track_album.reset(); delete_album.setParameter(0,album); delete_album.execute(); delete_album.reset(); db.commit(); } catch (FXExecuteException &){ db.rollback(); return false; } return true; } FXbool GMTrackDatabase::removeTracks(const FXIntList & tracks) { try { #ifdef DEBUG FXlong start = fxgetticks(); #endif db.begin(); for (FXint i=0;i0 && playlists[i-1]!=playlists[i]) j=1; insert_all.setParameter(0,playlists[i]); insert_all.setParameter(1,tracks[i]); insert_all.setParameter(2,j); insert_all.execute(); insert_all.reset(); } } catch (FXCompileException &){ return false; } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::removeTracksFromPlaylist(const FXIntList & queue,FXint playlist){ FXString query; db.begin(); if (queue.no()==1) { query.format("DELETE FROM playlist_tracks WHERE playlist == %d AND queue == %d;",playlist,queue[0]); if (!db.execute(query)) goto error; // Renumber queue following removed queue query.format("UPDATE playlist_tracks SET queue = queue - 1 WHERE playlist == %d AND queue > %d;",playlist,queue[0]); if (!db.execute(query)) goto error; } else { query.format("DELETE FROM playlist_tracks WHERE playlist == %d AND queue IN ( %d",playlist,queue[0]); for (FXint i=1;i " +GMStringVal(oldq) + " AND queue <= " + GMStringVal(newq) + ";"; else query = "UPDATE playlist_tracks SET queue = queue + 1 WHERE playlist == "+ GMStringVal(playlist) +" AND queue < " +GMStringVal(oldq) + " AND queue >= " + GMStringVal(newq) + ";"; if (!db.execute(query)) return false; query = "UPDATE playlist_tracks SET queue = " + GMStringVal(newq) + " WHERE playlist == " + GMStringVal(playlist) + " AND ROWID == " + GMStringVal(row) + ";"; if (!db.execute(query)) return false; return true; } /// Set the import date of a track FXbool GMTrackDatabase::setTrackImported(FXint track,FXlong tm){ try { update_track_importdate.setParameter(0,tm); update_track_importdate.setParameter(1,track); update_track_importdate.execute(); update_track_importdate.reset(); } catch (FXExecuteException & ){ return false; } return true; } /// Set the name of a track FXbool GMTrackDatabase::setTrackTitle(FXint track,const FXString & name){ FXString filename; try { update_track_title.setParameter(0,name); update_track_title.setParameter(1,track); update_track_title.execute(); update_track_title.reset(); } catch (FXExecuteException &){ return FALSE; } return true; } FXbool GMTrackDatabase::playedTrack(FXint track,FXlong time) { try { update_played.setParameter(0,time); update_played.setParameter(1,track); update_played.execute(); update_played.reset(); } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::setTrackYear(FXint track,FXuint year){ FXString mrl; try { update_track_year.setParameter(0,(FXint)year); update_track_year.setParameter(1,track); update_track_year.execute(); update_track_year.reset(); } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::setTrackYear(const FXIntList & tracks,FXuint year){ FXString mrl; try { for (FXint i=0;iappendItem(TagLib::ID3v1::genre(i).toCString(true)); } while(list_genres.execute()) { list_genres.getResult(0,id); list_genres.getResult(1,name); if (!genres.find(name.text())) list->appendItem(name); } } else { while(list_genres.execute()) { list_genres.getResult(0,id); list_genres.getResult(1,name); list->appendItem(name); } } list_genres.reset(); list->sortItems(); } catch(FXExecuteException &){ list->clearItems(); return FALSE; } return true; } FXbool GMTrackDatabase::listArtists(FXComboBox * list){ FXString name; FXint id; try { while(list_artists.execute()){ list_artists.getResult(0,id); list_artists.getResult(1,name); list->appendItem(name); } list_artists.reset(); list->sortItems(); } catch(FXExecuteException & ){ list->clearItems(); return FALSE; } return true; } FXbool GMTrackDatabase::listAlbums(FXComboBox * list,FXint album){ FXString name; FXint id; FXint artist; try { if (!queryArtist(artist,album)) return FALSE; list_albums_artist.setParameter(0,artist); while(list_albums_artist.execute()){ list_albums_artist.getResult(0,id); list_albums_artist.getResult(1,name); list->appendItem(name); } list_albums_artist.reset(); list->sortItems(); } catch(FXExecuteException & ){ list->clearItems(); return FALSE; } return true; } FXbool GMTrackDatabase::listTracks(FXIntList & list,FXint album,FXint genre/*=-1*/,FXint playlist/*=-1*/){ GMQuery query; FXint id; try { if (genre==-1) { if (playlist==-1) { list_tracks_from_album.setParameter(0,album); while(list_tracks_from_album.execute()){ list_tracks_from_album.getResult(0,id); list.append(id); } list_tracks_from_album.reset(); } else { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,genres,playlist_tracks WHERE playlist_tracks.track == tracks.id AND tracks.album == ? AND playlist_tracks.playlist == ?;"); query.setParameter(0,album); query.setParameter(1,playlist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } } else { if (playlist==-1) { list_tracks_from_album_genre.setParameter(0,album); list_tracks_from_album_genre.setParameter(1,genre); while(list_tracks_from_album_genre.execute()){ list_tracks_from_album_genre.getResult(0,id); list.append(id); } list_tracks_from_album_genre.reset(); } else { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,genres,playlist_tracks WHERE genres.id == tracks.genre AND playlist_tracks.track == tracks.id AND tracks.album == ? AND tracks.genre == ? AND playlist_tracks.playlist == ?;"); query.setParameter(0,album); query.setParameter(1,genre); query.setParameter(2,playlist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } } } catch(FXCompileException & e){ fxmessage("compile exception: %s\n",e.what()); list.clear(); return false; } catch(FXExecuteException & e){ fxmessage("execute exception: %s\n",e.what()); list.clear(); return false; } return true; } FXbool GMTrackDatabase::listTracks(FXIntList & list,FXint genre){ FXint id; try { list_tracks_genre_only.setParameter(0,genre); while(list_tracks_genre_only.execute()){ list_tracks_genre_only.getResult(0,id); list.append(id); } list_tracks_genre_only.reset(); } catch(FXExecuteException & e){ fxwarning("Exception: %s\n",e.what()); list.clear(); return false; } return true; } FXbool GMTrackDatabase::listTracksArtists(FXIntList & list,FXint artist,FXint genre/*=-1*/,FXint playlist/*=-1*/){ GMQuery query; FXint id; try { if (genre==-1) { if (playlist==-1) { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,albums,artists WHERE tracks.album = albums.id AND artists.id == albums.artist AND artists.id == ?;"); query.setParameter(0,artist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } else { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,albums,artists,playlist_tracks WHERE tracks.album == albums.id AND artists.id == albums.artist AND playlist_tracks.track == tracks.id AND artists.id == ? AND playlist_tracks.playlist == ? ;"); query.setParameter(0,artist); query.setParameter(1,playlist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } } else { if (playlist==-1) { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,albums,artists WHERE tracks.album = albums.id AND artists.id == albums.artist AND tracks.genre == ? AND artists.id == ?;"); query.setParameter(0,genre); query.setParameter(1,artist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } else { query.compile((GMDatabase*)this,"SELECT tracks.id FROM tracks,albums,artists,playlist_tracks WHERE tracks.album = albums.id AND artists.id == albums.artist AND playlist_tracks.track == tracks.id AND tracks.genre == ? AND artists.id == ? AND playlist_tracks.playlist == ?;"); query.setParameter(0,genre); query.setParameter(1,artist); query.setParameter(2,playlist); while(query.execute()) { query.getResult(0,id); list.append(id); } query.reset(); } } } catch(FXCompileException & e){ fxmessage("compile: %s\n",e.what()); list.clear(); return false; } catch(FXExecuteException & e){ fxmessage("execute: %s\n",e.what()); list.clear(); return false; } return true; } FXbool GMTrackDatabase::upgrade_to_2009() { if (!db.execute("ALTER TABLE albums RENAME TO albums_old;")) return false; if (!db.execute(create_albums)) return false; if (!db.execute("INSERT INTO albums (id, name, artist, year) SELECT albums_old.id, name, artist,year FROM albums_old,album_artist,tracks WHERE album_artist.album == albums_old.id AND tracks.album==albums_old.id GROUP BY albums_old.id;")) return false; if (!db.execute("DROP TABLE albums_old;")) return false; if (!db.execute("DROP TABLE album_artist;")) return false; if (!db.execute("ALTER TABLE tracks ADD COLUMN artist INTEGER;")) return false; if (!db.execute("ALTER TABLE tracks ADD COLUMN replay_gain REAL;")) return false; if (!db.execute("ALTER TABLE tracks ADD COLUMN replay_peak REAL;")) return false; if (!db.execute("UPDATE tracks SET artist = ( SELECT DISTINCT(albums.artist) FROM albums WHERE albums.id == tracks.album );")) return false; GMQuery q; q.compile(db,"UPDATE tracks SET replay_gain = ?, replay_peak = ?;"); FXdouble v=NAN; q.setParameter(0,v); q.setParameter(1,v); q.execute(); q.reset(); if (!db.hasTable("streams")) { if (!db.execute(create_streams)) return false; } if (sqlite3_libversion_number()>=SQVERSION(3,3,0)) { db.execute("CREATE INDEX IF NOT EXISTS tracks_album ON tracks(album);"); db.execute("CREATE INDEX IF NOT EXISTS playlist_tracks_idx ON playlist_tracks(track);"); } else { if (!db.hasIndex("tracks_album")) db.execute("CREATE INDEX tracks_album ON tracks(album);"); if (!db.hasIndex("playlist_tracks_idx")) db.execute("CREATE INDEX playlist_tracks_idx ON playlist_tracks(track);"); } db.setVersion(GOGGLESMM_DATABASE_SCHEMA_VERSION); /// Rebuild the database db.execute("VACUUM;"); return true; } void GMTrackDatabase::fix_genres() { FXint total=0; try { GMQuery count_tracks(&db,"SELECT COUNT(id) FROM tracks WHERE genre == 0;"); count_tracks.execute(); count_tracks.getResult(0,total); count_tracks.reset(); if (total>0) { FXint genre=0; if (queryGenre(genre,"Untitled",true)) { GMQuery fix; fix.compile(db,"UPDATE tracks SET genre = ? WHERE genre == 0;"); fix.setParameter(0,genre); fix.execute(); fix.reset(); } } } catch (FXCompileException &){ } catch (FXExecuteException &){ } } FXbool GMTrackDatabase::setup_tables() { FXString sql; FXint version = db.getVersion(); GMQuery list_tables; GMQuery list_index; try { if (version==GOGGLESMM_DATABASE_SCHEMA_VERSION) { return true; } if (version==2008) { if (upgrade_to_2009()) return true; } db.clear(); /// Create Tables if (!db.execute(create_tracks)) return FALSE; if (!db.execute(create_genres)) return FALSE; if (!db.execute(create_albums)) return FALSE; if (!db.execute(create_artists)) return FALSE; if (!db.execute(create_playlists)) return FALSE; if (!db.execute(create_playlist_tracks)) return FALSE; if (!db.execute(create_directories)) return FALSE; if (!db.execute(create_trigger_diradd)) return FALSE; if (!db.execute(create_streams)) return FALSE; db.execute("CREATE INDEX tracks_album ON tracks(album);"); db.execute("CREATE INDEX playlist_tracks_idx ON playlist_tracks(track);"); db.setVersion(GOGGLESMM_DATABASE_SCHEMA_VERSION); } catch (FXCompileException &){ return false; } catch (FXExecuteException &){ return false; } return true; } FXbool GMTrackDatabase::setup_queries(){ try { insert_root_component.compile(db,"INSERT INTO directories (id,parent,name) VALUES (NULL,NULL,?);"); insert_path_component.compile(db,"INSERT INTO directories (id,parent,name) VALUES (NULL,?,?);"); insert_track.compile(db,"INSERT INTO tracks VALUES ( NULL , ? , ? , ? , ? , ? , ? , 0 , 0 , ? , ? , ?, 0, ?, ?, ? );"); insert_genre.compile(db,"INSERT INTO genres VALUES ( NULL , ? );"); insert_artist.compile(db,"INSERT INTO artists VALUES ( NULL , ? );"); insert_album.compile(db,"INSERT INTO albums VALUES ( NULL , ?, ?, ?, ?, ? );"); query_filename.compile(db,"SELECT id FROM tracks WHERE path == ? AND mrl == ?;"); query_root_component.compile(db,"SELECT id FROM directories WHERE parent isnull AND name = ?;"); query_path_component.compile(db,"SELECT id FROM directories WHERE parent = ? AND name = ?;"); query_path.compile(db,"SELECT name FROM directories WHERE (select path || id || '/' from directories WHERE id = ? ) like path || id || '/%' order by path;"); query_track.compile(db,"SELECT path, mrl, albums.name, a1.name, a2.name, genres.name, title, time, no, tracks.year, tracks.replay_gain, tracks.replay_peak, albums.replay_gain, albums.replay_peak " "FROM tracks, albums, genres, artists AS a1, artists AS a2 " "WHERE albums.id == tracks.album " "ANd a1.id == albums.artist " "AND genres.id == tracks.genre " "AND a2.id == tracks.artist " "AND tracks.id == ?;"); query_genre.compile(db,"SELECT id FROM genres WHERE name == ?;"); query_artist.compile(db,"SELECT id FROM artists WHERE name == ?;"); query_artist_name.compile(db,"SELECT name FROM artists WHERE id == ?;"); query_album.compile(db,"SELECT id FROM albums WHERE name == ? AND artist == ?;"); query_album_name.compile(db,"SELECT name FROM albums WHERE id == ?;"); query_artist_with_album.compile(db,"SELECT artist FROM albums WHERE id == ?;"); query_artist_name_album.compile(db,"SELECT name FROM artists WHERE id == ( SELECT artist FROM albums WHERE id == ? );"); query_album_with_track.compile(db,"SELECT album,year FROM tracks WHERE id == ?;"); query_track_filename.compile(db,"SELECT mrl,path FROM tracks WHERE tracks.id == ? ;"); query_track_filename_by_album.compile(db,"SELECT mrl,path FROM tracks WHERE album == ? ORDER BY no LIMIT(1);"); query_track_genre_id.compile(db,"SELECT genre FROM tracks WHERE id == ?;"); query_artist_year.compile(db,"SELECT albums.artist,tracks.year FROM tracks,albums WHERE albums.id ==tracks.album AND tracks.id == ?;"); query_album_artists.compile(db,"SELECT albums.artist,album FROM tracks,albums WHERE albums.id ==tracks.album AND tracks.id == ?;"); update_played.compile(db,"UPDATE tracks SET playcount = playcount + 1, playdate = ? WHERE id == ?;"); list_genres.compile(db,"SELECT id, name FROM genres WHERE id IN (SELECT DISTINCT(genre) FROM tracks);"); list_artists.compile(db,"SELECT id,name FROM artists;"); list_albums_artist.compile(db,"SELECT albums.id, albums.name FROM albums WHERE albums.artist == ? ;"); list_tracks_from_album.compile(db,"SELECT id FROM tracks WHERE album == ?"); list_tracks_from_album_genre.compile(db,"SELECT id FROM tracks WHERE album == ? AND genre == ?;"); list_tracks_genre_only.compile(db,"SELECT id FROM tracks WHERE genre == ?;"); query_playlist_queue.compile(db,"SELECT MAX(queue) FROM playlist_tracks WHERE playlist == ?;"); insert_track_playlist.compile(db,"INSERT INTO playlist_tracks VALUES ( ? , ? , ?);"); fix_genres(); } catch (FXCompileException & e){ fxmessage("Compile Exception: %s\n",e.what()); return FALSE; } return true; } FXbool GMTrackDatabase::queryGenre(FXint & result,const FXString & name,FXbool insert){ result=-1; try { query_genre.setParameter(0,name); query_genre.execute(); query_genre.getResult(0,result); query_genre.reset(); if (result==-1 && insert) { insert_genre.setParameter(0,name); insert_genre.execute(); result = db.lastInsertRow(); insert_genre.reset(); } } catch (FXExecuteException &){ result=-1; return FALSE; } return true; } /* FXbool GMTrackDatabase::queryGenre(FXString & result,FXint trackid){ result=FXString::null; try { query_track_genre.setParameter(0,trackid); query_track_genre.execute(); query_track_genre.getResult(0,result); query_track_genre.reset(); } catch (FXExecuteException & e){ result=FXString::null; return FALSE; } return true; } */ FXbool GMTrackDatabase::getTrackGenre(FXint & genre,FXint trackid) { genre=-1; try { query_track_genre_id.setParameter(0,trackid); query_track_genre_id.execute(); query_track_genre_id.getResult(0,genre); query_track_genre_id.reset(); } catch (FXExecuteException &){ genre=-1; return FALSE; } return true; } FXbool GMTrackDatabase::queryArtist(FXint & result,const FXString & name,FXbool insert){ result=-1; try { query_artist.setParameter(0,name); query_artist.execute(); query_artist.getResult(0,result); query_artist.reset(); if (result==-1 && insert) { insert_artist.setParameter(0,name); insert_artist.execute(); result = db.lastInsertRow(); insert_artist.reset(); } } catch (FXExecuteException &){ result=-1; return FALSE; } return true; } FXbool GMTrackDatabase::queryArtist(FXint & result,FXint album){ result=-1; try { query_artist_with_album.setParameter(0,album); query_artist_with_album.execute(); query_artist_with_album.getResult(0,result); query_artist_with_album.reset(); } catch (FXExecuteException &){ result=-1; return FALSE; } return true; } FXbool GMTrackDatabase::queryArtist(FXString & result,FXint album){ result=FXString::null; try { query_artist_name_album.setParameter(0,album); query_artist_name_album.execute(); query_artist_name_album.getResult(0,result); query_artist_name_album.reset(); } catch (FXExecuteException &){ result=FXString::null; return FALSE; } return true; } FXbool GMTrackDatabase::queryAlbum(FXint & album,FXint & year,FXint track){ album=-1; year=0; try { query_album_with_track.setParameter(0,track); query_album_with_track.execute(); query_album_with_track.getResult(0,album); query_album_with_track.getResult(1,year); query_album_with_track.reset(); } catch (FXExecuteException &){ album=-1; year=0; return false; } return true; } FXbool GMTrackDatabase::updateAlbum(FXint & result,const GMTrack & track,FXint artist){ result=-1; try { query_album.setParameter(0,track.album); query_album.setParameter(1,artist); query_album.execute(); query_album.getResult(0,result); query_album.reset(); if (result==-1) { insert_album.setParameter(0,track.album); insert_album.setParameter(1,artist); insert_album.setParameter(2,track.year); insert_album.setParameter(3,track.album_gain); insert_album.setParameter(4,track.album_peak); insert_album.execute(); result = db.lastInsertRow(); insert_album.reset(); } else { update_album.setParameter(0,track.year); update_album.setParameter(1,track.album_gain); update_album.setParameter(2,track.album_peak); update_album.setParameter(3,result); update_album.execute(); update_album.reset(); } } catch (FXExecuteException & e){ fxmessage("Exception: %s\n",e.what()); result=-1; return FALSE; } return true; } FXbool GMTrackDatabase::queryAlbum(FXint & result,const FXString & name,FXint artist,FXint year,FXdouble gain,FXdouble peak,FXbool insert){ result=-1; try { query_album.setParameter(0,name); query_album.setParameter(1,artist); query_album.execute(); query_album.getResult(0,result); query_album.reset(); if (result==-1 && insert) { insert_album.setParameter(0,name); insert_album.setParameter(1,artist); insert_album.setParameter(2,year); insert_album.setParameter(3,gain); insert_album.setParameter(4,peak); insert_album.execute(); result = db.lastInsertRow(); insert_album.reset(); } } catch (FXExecuteException & e){ fxmessage("Exception: %s\n",e.what()); result=-1; return FALSE; } return true; } FXbool GMTrackDatabase::queryAlbum(FXString & name,FXint album){ name=FXString::null; try { query_album_name.setParameter(0,album); query_album_name.execute(); query_album_name.getResult(0,name); query_album_name.reset(); } catch (FXExecuteException &){ name=FXString::null; return FALSE; } return true; } FXbool GMTrackDatabase::vacuum() { #ifdef DEBUG FXlong end, start; start = fxgetticks(); #endif /// Remove empty playlists ? FIXME: may be not... /// if (!db.execute("DELETE FROM playlists WHERE id NOT IN (SELECT DISTINCT(playlist) FROM playlist_tracks);")) // return false; db.begin(); #ifdef DEBUG fxmessage("Reorder Playlists\n"); #endif /// Reorder Playlists if (!reorderPlaylists()) goto error; #ifdef DEBUG fxmessage("Remove Empty Albums\n"); #endif /// Remove empty albums if (!db.execute("DELETE FROM albums WHERE id NOT IN (SELECT DISTINCT(album) FROM tracks);")) goto error; #ifdef DEBUG fxmessage("Remove unused artists\n"); #endif /// Remove unused artists if (!db.execute("DELETE FROM artists WHERE id NOT IN (SELECT DISTINCT(artist) FROM albums) ANd id NOT IN (SELECT DISTINCT(artist) FROM tracks);")) goto error; #ifdef DEBUG fxmessage("Remove unused genres\n"); #endif /// Remove unused genres if (!db.execute("DELETE FROM genres WHERE id NOT IN (SELECT DISTINCT(genre) FROM tracks) AND id NOT IN (SELECT DISTINCT(genre) FROM streams);")) goto error; #ifdef DEBUG fxmessage("Remove empty leafs\n"); #endif /// Remove empty leafs do { if (!db.execute("DELETE FROM directories WHERE id NOT IN (SELECT DISTINCT(parent) FROM directories) AND id NOT IN (SELECT DISTINCT(path) FROM tracks);")) goto error; } while (db.changes()>0); last_path=-1; /// commit changes db.commit(); #ifdef DEBUG end = fxgetticks(); fxmessage("Vacuum Database in %ld ticks\n",end-start); #endif return true; error: db.rollback(); return false; } FXbool GMTrackDatabase::exportList(const FXString & filename,FXint playlist,FXuint filetype,FXuint opts){ const FXchar * c_artist; const FXchar * c_album; const FXchar * c_title; const FXchar * c_genre; FXint time; FXint no; FXint id; FXint cnt=1; FXint year; FILE * fp = NULL; FXString query; FXString title; FXString file; FXString basepath=FXPath::directory(filename); GMQuery list; try { query = "SELECT tracks.id,title,artists.name,albums.name,genres.name,no,time,tracks.year " "FROM tracks, genres, albums, artists"; if (playlist>=0) query+=", playlist_tracks"; query+=" WHERE genres.id == tracks.genre AND " "albums.artist == artists.id AND " "tracks.album == albums.id"; if (playlist>=0) { query+=" AND playlist_tracks.track == tracks.id"; query+=" AND playlist_tracks.playlist == "+GMStringVal(playlist); query+=" ORDER BY playlist_tracks.queue; "; title=getPlaylistName(playlist); } else { query+=";"; } list.compile(db,query); FILE * fp = fopen(filename.text(),"w"); if (!fp) return false; if (filetype==PLAYLIST_XSPF) { fprintf(fp,""); fprintf(fp,"\n"); if (!title.empty()) fprintf(fp,"\t%s\n",title.text()); fprintf(fp,"\t\n"); } else if (filetype==PLAYLIST_M3U_EXTENDED) { fprintf(fp,"#EXTM3U\n"); } else if (filetype==PLAYLIST_PLS) { fprintf(fp,"[playlist]\n"); } else if (filetype==PLAYLIST_CSV) { fprintf(fp,"No,Title,Album,Artist,Genre,Duration,Year,Filename\n"); } while(list.execute()){ list.getResult(0,id); c_title = list.getResult(1); c_artist = list.getResult(2); c_album = list.getResult(3); c_genre = list.getResult(4); list.getResult(5,no); list.getResult(6,time); list.getResult(7,year); file = getTrackFilename(id); if (opts&PLAYLIST_OPTIONS_RELATIVE) file = FXPath::relative(basepath,file); if (filetype==PLAYLIST_XSPF) { fprintf(fp,"\t\t\n"); fprintf(fp,"\t\t\t%s\n",GMURL::fileToURL(gm_url_encode(file)).text()); fprintf(fp,"\t\t\t%s\n",c_artist); fprintf(fp,"\t\t\t%s\n",c_album); fprintf(fp,"\t\t\t%s\n",c_title); fprintf(fp,"\t\t\t%d\n",time*1000); fprintf(fp,"\t\t\t%u\n",no); fprintf(fp,"\t\t\n"); } else if (filetype==PLAYLIST_M3U_EXTENDED) { fprintf(fp,"#EXTINF:%d,%s - %s\n",time,c_artist,c_title); fprintf(fp,"%s\n",file.text()); } else if (filetype==PLAYLIST_M3U) { fprintf(fp,"%s\n",file.text()); } else if (filetype==PLAYLIST_PLS) { fprintf(fp,"File%d=%s\n",cnt,file.text()); fprintf(fp,"Title%d=%s - %s\n",cnt,c_artist,c_title); fprintf(fp,"Length%d=%d\n",cnt,time); cnt++; } else if (filetype==PLAYLIST_CSV){ fprintf(fp,"%d,\"%s\",\"%s\",\"%s\",\"%s\",%d,%d,\"%s\"\n",no,c_title,c_album,c_artist,c_genre,time,year,file.text()); } } list.reset(); if (filetype==PLAYLIST_XSPF) { fprintf(fp,"\t\n"); fprintf(fp,""); } else if (filetype==PLAYLIST_PLS){ fprintf(fp,"Version=2\n"); fprintf(fp,"NumberOfEntries=%d",cnt-1); } fclose(fp); fp=NULL; } catch (FXCompileException &){ if (fp) fclose(fp); return false; } catch (FXExecuteException &){ if (fp) fclose(fp); return false; } return true; } gogglesmm-0.12.7/src/gogglesmm.xml0000644000175000001440000000152711436014013015575 0ustar sxjusers gogglesmm-0.12.7/src/GMTrackList.h0000644000175000001440000003753311670041747015413 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Icon List Widget (under LGPL3) * * Copyright (C) 1999,2011 by Jeroen van der Zijp. All Rights Reserved. * * --- * * Modifications * * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTRACKLIST_H #define GMTRACKLIST_H enum { COLUMN_JUSTIFY_NORMAL=0, COLUMN_JUSTIFY_CENTER_RIGHT_ALIGNED, COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED, COLUMN_JUSTIFY_RIGHT, }; /// Icon list styles enum { TRACKLIST_EXTENDEDSELECT = 0, /// Extended selection mode TRACKLIST_SINGLESELECT = 0x00100000, /// At most one selected item TRACKLIST_BROWSESELECT = 0x00200000, /// Always exactly one selected item TRACKLIST_MULTIPLESELECT = 0x00300000, /// Multiple selection mode TRACKLIST_NORMAL = ICONLIST_EXTENDEDSELECT }; class GMTrackList; class GMColumn; class GMTrackItem { friend class GMTrackList; protected: FXint id; FXuchar state; protected: virtual const FXString * getColumnData(FXint,FXString &,FXuint &,FXint &) const { return NULL; } virtual FXIcon * getIcon() const { return NULL; } public: enum { SELECTED = 1, /// Selected FOCUS = 2, /// Focus DRAGGABLE = 4, /// Draggable }; public: GMTrackItem() : state(0) {} GMTrackItem(FXint tid) : id(tid),state(0) {} /// Return track item id FXint getId() const { return id; } /// Select item virtual void setSelected(FXbool selected); /// Return true if this item is selected FXbool isSelected() const { return (state&SELECTED)!=0; } /// Make item draw as focused virtual void setFocus(FXbool focus); /// Return true if item has focus FXbool hasFocus() const { return (state&FOCUS)!=0; } /// Make item draggable virtual void setDraggable(FXbool draggable); /// Return true if this item is draggable FXbool isDraggable() const { return (state&DRAGGABLE)!=0; } /// Destructor virtual ~GMTrackItem() {} }; class GMDBTrackItem; /// Icon item collate function typedef FXint (*GMTrackListSortFunc)(const GMTrackItem*,const GMTrackItem*); struct GMColumn { FXString name; FXint type; FXint size; FXint index; GMTrackListSortFunc ascending; GMTrackListSortFunc descending; FXbool show; FXbool default_show; FXbool default_browser_show; FXObject* target; FXSelector message; GMColumn() : size(60),index(0),show(false),target(NULL),message(0) {} GMColumn(const FXchar * n,FXuint t,GMTrackListSortFunc a,GMTrackListSortFunc b,FXint sz=60,FXbool def_show=true,FXbool def_browser_show=true,FXint idx=0,FXObject* tgt=NULL,FXSelector sel=0) : name(n),type(t),size(sz),index(idx),ascending(a),descending(b),show(true),default_show(def_show),default_browser_show(def_browser_show),target(tgt),message(sel) {} }; typedef FXArray GMColumnList; /// List of FXIconItem's typedef FXArray GMTrackItemList; class GMTrackList : public FXScrollArea { FXDECLARE(GMTrackList) friend class GMTrackItem; protected: FXHeader* header; // Header control GMTrackItemList items; // Item List FXint anchor; // Anchor item FXint current; // Current item FXint extent; // Extent item FXint cursor; // Cursor item FXint viewable; // Visible item FXint active; FXFont *font; // Font FXFont *activeFont; GMTrackListSortFunc sortfunc; // Item sort function FXColor textColor; // Text color FXColor selbackColor; // Selected back color FXColor seltextColor; // Selected text color FXColor rowColor; FXColor activeColor; FXColor activeTextColor; FXint lineHeight; // Item height FXint anchorx; // Rectangular selection FXint anchory; FXint currentx; FXint currenty; FXint ratingx; FXint ratingy; FXint ratingl; FXint grabx; // Grab point x FXint graby; // Grab point y FXString help; // Help text FXbool state; // State of item FXint sortMethod; FXString starset; FXString starunset; protected: GMTrackList(); void draw(FXDC& dc,FXEvent *event,FXint index,FXint x,FXint y,FXint w,FXint h,FXint dw) const; void recompute(); virtual void moveContents(FXint x,FXint y); void clearRating(); private: GMTrackList(const GMTrackList&); GMTrackList &operator=(const GMTrackList&); public: long onPaint(FXObject*,FXSelector,void*); long onEnter(FXObject*,FXSelector,void*); long onLeave(FXObject*,FXSelector,void*); long onUngrabbed(FXObject*,FXSelector,void*); long onKeyPress(FXObject*,FXSelector,void*); long onKeyRelease(FXObject*,FXSelector,void*); long onLeftBtnPress(FXObject*,FXSelector,void*); long onLeftBtnRelease(FXObject*,FXSelector,void*); long onRightBtnPress(FXObject*,FXSelector,void*); long onRightBtnRelease(FXObject*,FXSelector,void*); long onMotion(FXObject*,FXSelector,void*); long onQueryTip(FXObject*,FXSelector,void*); long onQueryHelp(FXObject*,FXSelector,void*); long onTipTimer(FXObject*,FXSelector,void*); long onCmdSelectAll(FXObject*,FXSelector,void*); long onCmdDeselectAll(FXObject*,FXSelector,void*); long onCmdSelectInverse(FXObject*,FXSelector,void*); long onCmdArrangeByRows(FXObject*,FXSelector,void*); long onUpdArrangeByRows(FXObject*,FXSelector,void*); long onCmdArrangeByColumns(FXObject*,FXSelector,void*); long onUpdArrangeByColumns(FXObject*,FXSelector,void*); long onCmdShowDetails(FXObject*,FXSelector,void*); long onUpdShowDetails(FXObject*,FXSelector,void*); long onCmdShowBigIcons(FXObject*,FXSelector,void*); long onUpdShowBigIcons(FXObject*,FXSelector,void*); long onCmdShowMiniIcons(FXObject*,FXSelector,void*); long onUpdShowMiniIcons(FXObject*,FXSelector,void*); long onChgHeader(FXObject*,FXSelector,void*); long onClkHeader(FXObject*,FXSelector,void*); long onCmdHeader(FXObject*,FXSelector,void*); long onUpdHeader(FXObject*,FXSelector,void*); long onHeaderRightBtnRelease(FXObject*,FXSelector,void*); long onFocusIn(FXObject*,FXSelector,void*); long onFocusOut(FXObject*,FXSelector,void*); long onClicked(FXObject*,FXSelector,void*); long onDoubleClicked(FXObject*,FXSelector,void*); long onTripleClicked(FXObject*,FXSelector,void*); long onCommand(FXObject*,FXSelector,void*); long onAutoScroll(FXObject*,FXSelector,void*); long onLookupTimer(FXObject*,FXSelector,void*); long onCmdSetValue(FXObject*,FXSelector,void*); long onCmdGetIntValue(FXObject*,FXSelector,void*); long onCmdSetIntValue(FXObject*,FXSelector,void*); long onMouseLeave(FXObject*,FXSelector,void*); long onWheelTimeout(FXObject*,FXSelector,void*); public: enum { ID_HEADER=FXScrollArea::ID_LAST, ID_SELECT_ALL, ID_DESELECT_ALL, ID_SELECT_INVERSE, ID_WHEEL_TIMEOUT, ID_LAST }; public: /// Construct icon list with no items in it initially GMTrackList(FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=TRACKLIST_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0); /// Get the unique item id FXint getItemId(FXint index) const { return items[index]->id; } /// Set the sort method void setSortMethod(FXint m) { sortMethod=m; } /// Get the sort method FXint getSortMethod() const { return sortMethod; } /// Mark the list as unsorted void markUnsorted(); /// Create server-side resources virtual void create(); /// Detach server-side resources virtual void detach(); /// Recalculate layout virtual void recalc(); /// Perform layout virtual void layout(); #if FOXVERSION < FXVERSION(1,7,0) virtual FXint getViewportHeight(); #else /// Return visible area y position virtual FXint getVisibleY() const; /// Return visible area height virtual FXint getVisibleHeight() const; #endif /// Compute and return content width virtual FXint getContentWidth(); /// Return content height virtual FXint getContentHeight(); /// Icon list can receive focus #if FOXVERSION < FXVERSION(1,7,0) virtual bool canFocus() const; #else virtual FXbool canFocus() const; #endif /// Move the focus to this window virtual void setFocus(); /// Remove the focus from this window virtual void killFocus(); /// Return number of items FXint getNumItems() const { return items.no(); } /// Return header control FXHeader* getHeader() const { return header; } /// Return the header data. GMColumn * getHeaderData(FXint i) const { return reinterpret_cast(header->getItemData(i)); } /// Return the header type FXuint getHeaderType(FXint i) const { return ( (i>=0 && igetNumItems()) ? ((reinterpret_cast(header->getItemData(i)))->type) : -1); } /// Append header with given text, size and column data void appendHeader(const FXString & label,FXint size,GMColumn * data); /// Remove header at index void removeHeader(FXint index); /// Return number of headers FXint getNumHeaders() const; /// Return index of given header type if displayed, otherwise -1 FXint getHeaderByType(FXuint type) const; /// Remove All Headers void clearHeaders(); /// Save Header Configuration void saveHeaders(); /// Return the item at the given index GMTrackItem *getItem(FXint index) const; /// Replace the item with a [possibly subclassed] item FXint setItem(FXint index,GMTrackItem* item,FXbool notify=false); /// Insert a new [possibly subclassed] item at the give index FXint insertItem(FXint index,GMTrackItem* item,FXbool notify=false); /// Append a [possibly subclassed] item to the end of the list FXint appendItem(GMTrackItem* item,FXbool notify=false); /// Prepend a [possibly subclassed] item to the end of the list FXint prependItem(GMTrackItem* item,FXbool notify=false); /// Move item from oldindex to newindex FXint moveItem(FXint newindex,FXint oldindex,FXbool notify=false); /// Extract item from list GMTrackItem* extractItem(FXint index,FXbool notify=false); /// Remove item from list void removeItem(FXint index,FXbool notify=false); /// Remove all items from list void clearItems(FXbool notify=false); /// Return item height FXint getLineHeight() const { return lineHeight; } /// Return index of item at x,y, or -1 if none virtual FXint getItemAt(FXint x,FXint y) const; /// Scroll to make item at index visible virtual void makeItemVisible(FXint index); /// Return true if item at index is selected FXbool isItemSelected(FXint index) const; /// Return true if item at index is current FXbool isItemCurrent(FXint index) const; /// Return true if item at index is visible FXbool isItemVisible(FXint index) const; /// Return true if item at index is enabled FXbool isItemEnabled(FXint index) const; /// Return item hit code: 0 outside, 1 icon, 2 text FXint hitItem(FXint index,FXint x,FXint y,FXint ww=1,FXint hh=1) const; /// Repaint item at index void updateItem(FXint index) const; /// Select item at index virtual FXbool selectItem(FXint index,FXbool notify=false); /// Deselect item at index virtual FXbool deselectItem(FXint index,FXbool notify=false); /// Toggle item at index virtual FXbool toggleItem(FXint index,FXbool notify=false); /// Select items in rectangle virtual FXbool selectInRectangle(FXint x,FXint y,FXint w,FXint h,FXbool notify=false); /// Extend selection from anchor index to index virtual FXbool extendSelection(FXint index,FXbool notify=false); /// Deselect all items virtual FXbool killSelection(FXbool notify=false); /// Change current item index virtual void setCurrentItem(FXint index,FXbool notify=false); /// Return current item index, or -1 if none FXint getCurrentItem() const { return current; } /// Change anchor item index void setAnchorItem(FXint index); /// Return anchor item index, or -1 if none FXint getAnchorItem() const { return anchor; } /// Return index of item under cursor, or -1 if none FXint getCursorItem() const { return cursor; } /// Change active item index void setActiveItem(FXint index); /// Return active item index, or -1 if none FXint getActiveItem() const { return (active==-1) ? current : active ; } /// Sort items void sortItems(); /// Return sort function GMTrackListSortFunc getSortFunc() const { return sortfunc; } /// Change sort function void setSortFunc(GMTrackListSortFunc func){ sortfunc=func; } /// Change text font void setFont(FXFont* fnt); /// Return text font FXFont* getFont() const { return font; } /// Change active text font void setActiveFont(FXFont* fnt); /// Return active text font FXFont* getActiveFont() const { return activeFont; } /// Return normal text color FXColor getTextColor() const { return textColor; } /// Change normal text color void setTextColor(FXColor clr); /// Return selected text background FXColor getSelBackColor() const { return selbackColor; } /// Change selected text background void setSelBackColor(FXColor clr); /// Return selected text color FXColor getSelTextColor() const { return seltextColor; } /// Change selected text color void setSelTextColor(FXColor clr); /// Return active text color FXColor getActiveTextColor() const { return activeTextColor; } /// Change active text color void setActiveTextColor(FXColor clr); /// Return row color FXColor getRowColor() const { return rowColor; } /// Change the row color void setRowColor(FXColor clr); /// Return active color FXColor getActiveColor() const { return activeColor; } /// Change the active color void setActiveColor(FXColor clr); /// Get the current icon list style FXuint getListStyle() const; /// Set the current icon list style. void setListStyle(FXuint style); /// Set the status line help text for this widget void setHelpText(const FXString& text); /// Get the status line help text for this widget const FXString& getHelpText() const { return help; } /// Save list to a stream virtual void save(FXStream& store) const; /// Load list from a stream virtual void load(FXStream& store); /// Destructor virtual ~GMTrackList(); }; #endif gogglesmm-0.12.7/src/GMTrackDatabase.h0000644000175000001440000003416211526346513016176 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTRACKDATABASE_H #define GMTRACKDATABASE_H #include "gmdefs.h" class GMTrackList; enum { PLAYLIST_M3U, PLAYLIST_M3U_EXTENDED, PLAYLIST_XSPF, PLAYLIST_PLS, PLAYLIST_CSV }; enum { PLAYLIST_OPTIONS_RELATIVE = 0x1 }; class GMTrackDatabase { private: GMDatabase db; public: /// Browse Queries /// ------------------------------------------------------------------------ GMQuery list_genres; /// Insert Queries /// ------------------------------------------------------------------------ GMQuery insert_root_component; GMQuery insert_path_component; GMQuery insert_track; /// Insert Track GMQuery insert_genre; /// Insert Genre GMQuery insert_artist; /// Insert Artist; GMQuery insert_album; /// Insert Album; // GMQuery insert_album_artist; /// Insert Album-Artist Assoc; GMQuery insert_track_playlist; /// Insert Track into Playlist GMQuery query_filename; /// Query filename GMQuery query_root_component; GMQuery query_path_component; GMQuery query_path; GMQuery query_genre; /// Query unique genre GMQuery query_album; /// Query unique album from artist GMQuery query_album_name; /// Query album name GMQuery query_artist; /// Query unique artist GMQuery query_artist_with_album;/// Query artist by album GMQuery query_artist_name; /// Query Artist Name for id GMQuery query_track; /// Query track GMQuery query_track_genre; /// Query track genre GMQuery query_playlist_queue; /// Get the max playlist queue GMQuery query_track_filename; /// Query filename by track id GMQuery query_track_filename_by_album; GMQuery query_track_genre_id; /// Query Track Genre ID GMQuery query_album_with_track; /// Query album by track GMQuery query_artist_name_album;/// Query artist by album GMQuery query_artist_year; /// Query artist, year for track GMQuery query_album_artists; /// Query artist and album for track GMQuery list_artists; GMQuery list_tracks_genre_only; /// List Tracks that have a certain genre GMQuery list_tracks_from_album; /// List Tracks from Album GMQuery list_tracks_from_album_genre; /// List Tracks from Album and Genre GMQuery list_albums_artist; /// Delete Queries /// ------------------------------------------------------------------------ GMQuery delete_artist; /// Delete Artist GMQuery delete_genre; /// Delete Genre GMQuery delete_album; /// Delete Album GMQuery delete_track; /// Delete Track GMQuery delete_track_artist; /// Delete Tracks from Artist GMQuery delete_track_album; /// Delete Tracks from Album GMQuery delete_albums_artist; /// Delete Album from Artist in Album List GMQuery delete_track_from_playlist; /// Delete track from specific playlist GMQuery delete_track_from_playlists; /// Delete track from all playlists GMQuery delete_album_from_playlists; /// Delete tracks from album from all playlists GMQuery delete_artist_from_playlists; /// Delete tracks from artist from all playlists GMQuery update_mrl; /// Update Name of Artist GMQuery update_track; /// Update track GMQuery update_album; /// Update Album GMQuery update_track_title; /// Update track title GMQuery update_track_year; /// Update Track Year GMQuery update_played; /// Update Track as played GMQuery update_track_genre; /// Update track genre GMQuery update_track_genre_id; /// Update track genre GMQuery update_track_no; /// Update track & disc no GMQuery update_track_disc; // Update disc no GMQuery update_track_track; /// Update track no GMQuery update_track_artist; /// Update track artist GMQuery update_track_importdate; /// Update track importdate; GMQuery query_track_no; /// Update track no GMQuery update_artist_album_id; /// Update artist in album_artist (with album id) GMQuery update_track_album_id; /// Update track album GMQuery insert_album_existing; /// Create new album entry based on existing GMQuery insert_album_existing_name; /// Create new album entry based on existing GMQuery query_album_existing; /// Create new album entry based on existing GMQuery query_artist_album; /// Query Artist Name for id protected: void setup_insert_queries(); void clear_insert_queries(); FXbool upgrade_to_2009(); FXbool reorderPlaylists(); protected: FXbool queryGenre(FXint & result,const FXString & name,FXbool insert); // FXbool queryGenre(FXString & result,FXint trackid); FXbool queryArtist(FXint & result,const FXString & name,FXbool insert); FXbool queryArtist(FXint & result,FXint album); FXbool queryArtist(FXString & result,FXint album); FXbool queryAlbum(FXint & result,const FXString & name,FXint artist,FXint year,FXdouble gain,FXdouble peak,FXbool insert); FXbool queryAlbum(FXString & name,FXint album); FXbool queryAlbum(FXint & album,FXint & year, FXint track); FXbool updateAlbum(FXint &album,const GMTrack&,FXint artist); FXbool getTrackGenre(FXint & genre,FXint trackid); void addPath(const FXString & path,FXint & id); FXbool findPath(const FXString & path,FXint & id); FXbool setup_tables(); FXbool setup_queries(); void fix_genres(); public: /// Constructor GMTrackDatabase(); GMDatabase * database() { return &db; } FXbool clearTracks(FXbool removeplaylists); /// Clear Database void clear(); /// Initialize the database. Return FALSE if failed else TRUE FXbool init(const FXString & filename,FXbool checkversion=false); ///======================================================================================= /// QUERY ITEMS ///======================================================================================= FXbool getStream(FXint id,GMStream & info); /// Return Track Info FXbool getTrack(FXint id,GMTrack & info); /// Return artist, album id FXbool getTrackAssociation(FXint id,FXint & artist,FXint & album); /// Return filename for track FXString getTrackFilename(FXint id); /// Return a list of filenames FXbool getTrackFilenames(FXIntList & ids,FXStringList & filenames,FXLongList & importdates ,const FXString & root=FXString::null); /// Return list of filenames void getTrackFilenames(const FXIntList & tracks,FXStringList & filenames); FXString getPathName(FXint id); FXbool getAlbumTrack(FXint id,FXString & path); /// Return the album path FXint getAlbumPath(FXint id); /// Return album id for track FXint getTrackAlbum(FXint id); /// Return Name for given album FXString getAlbumName(FXint id); /// Return Artist for given album FXString getAlbumArtist(FXint id); /// Return Artist Name for given id FXString getArtistName(FXint id); /// Return Genre Name for give id FXString getGenreName(FXint id); /// Return Play list name for given id FXString getPlaylistName(FXint id); /// Return number of tracks in database FXint getNumTracks(); /// Return number of tracks in database FXint getNumStreams(); /// Return number of albums in database FXint getNumAlbums(); /// Return number of artists in database FXint getNumArtists(); /// Return total time of all tracks FXint getTotalTime(); /// Mark track as played FXbool playedTrack(FXint id,FXlong t); /// Update Playlist Queue FXbool updateTrackPlaylists(FXint playlist,FXIntList & tracks); FXbool trackInPlaylist(FXint track,FXint playlist); ///======================================================================================= /// INSERTING ITEMS ///======================================================================================= /// Check if we have a track FXbool hasTrack(const FXString &,FXint & id); /// Check if we have file in directory FXbool hasTrack(const FXString & directory,const FXString & filename,FXint & id); /// Insert Track into database FXbool insertTrack(const GMTrack & info,FXint & id); /// Uodate Track in database FXbool updateTrack(FXint id,const GMTrack & info); /// Insert Playlist into database FXbool insertPlaylist(const FXString & name,FXint & id); /// Insert Track in Playlist FXbool insertTrackInPlaylist(FXint playlist,FXint & track); /// Insert Track in Playlist FXbool insertTrackInPlaylist(FXint playlist,FXIntList & tracks); /// Remove Queue numbers from Playlist FXbool removeTracksFromPlaylist(const FXIntList & queue,FXint playlist); FXbool insertStream(const FXString & url,const FXString & description,const FXString & genre); ///======================================================================================= /// DELETING ITEMS ///======================================================================================= void beginDelete(); /// Remove Track from database FXbool removeTrack(FXint id); /// Remove Track from database FXbool removeTracks(const FXIntList &ids); /// Remove Album from database FXbool removeAlbum(FXint id); /// Remove Artist from database FXbool removeArtist(FXint id); /// Remove Genre from database FXbool removeGenre(FXint id,FXbool update_tracks=true); /// Remove Playlist from database FXbool removePlaylist(FXint id); /// Remove Stream FXbool removeStream(FXint id); void endDelete(FXbool vacuum=true); /// Synchronize all tables and makes sure no empty entries are left behind. FXbool vacuum(); ///======================================================================================= /// EDITING ITEMS ///======================================================================================= void beginEdit(); /// Set Track No FXbool setTrackDiscNumber(FXint id,FXuint no); /// Set Track Disc FXbool setTrackDisc(FXint id,FXushort disc); FXbool setTrackDisc(const FXIntList & ids,FXushort disc); /// Set Track Number FXbool setTrackNumber(FXint id,FXushort no); /// Set Track Title FXbool setTrackTitle(FXint id,const FXString & name); /// Set Track Genre FXbool setTrackGenre(FXint id,const FXString & name); FXbool setTrackGenre(const FXIntList & ids,const FXString & name); /// Set Track Album FXbool setTrackAlbum(FXint id,const FXString & name); FXbool setTrackAlbum(const FXIntList & ids,const FXString & name,FXbool sameartist); /// Set Track Artist FXbool setTrackAlbumArtist(FXint id,const FXString & name,const FXString & album_title); FXbool setTrackAlbumArtist(const FXIntList & ids,const FXString & name,const FXString & album_title); /// Set Track Artist FXbool setTrackAlbumArtist(FXint id,const FXString & name); /// Set Track Artist FXbool setTrackArtist(FXint id,const FXString & name); FXbool setTrackArtist(const FXIntList & ids,const FXString & name); /// Set Track Year FXbool setTrackYear(FXint id,FXuint year); FXbool setTrackYear(const FXIntList & ids,FXuint year); /// Change the filename of id void setTrackFilename(FXint id,const FXString & filename); /// Set Playlist Name FXbool setPlaylistName(FXint id,const FXString & name); /// Move oldq to newq FXbool moveTrack(FXint playlist,FXint oldq,FXint newq); /// Mark track as imported FXbool setTrackImported(FXint id,FXlong tm); void endEdit(FXbool vacuum=true); FXbool setStreamFilename(FXint id,const FXString & filename); FXbool setStreamDescription(FXint id,const FXString & description); FXbool setStreamGenre(FXint id,const FXString & genre); FXbool setStreamBitrate(FXint id,FXint rate); ///======================================================================================= /// LISTING ITEMS ///======================================================================================= /// List Genres FXbool listGenres(FXComboBox * list,FXbool insert_default=TRUE); /// List Artists with optional genre FXbool listArtists(FXList * list,FXIcon * icon,FXint genre=-1,FXint playlist=-1); /// List Artists FXbool listArtists(FXComboBox * list); /// List Albums from Artist FXbool listAlbums(FXComboBox * list,FXint album); /// List Tracks from Album FXbool listTracks(FXIntList & list,FXint album,FXint genre,FXint playlist=-1); /// List Tracks with genre FXbool listTracks(FXIntList & list,FXint genre); FXbool listTracksArtists(FXIntList & list,FXint artist,FXint genre,FXint playlist=-1); /// List Playlists FXbool listPlaylists(FXIntList & ids); ///======================================================================================= /// EXPORT ///======================================================================================= FXbool exportList(const FXString & filename,FXint playlist,FXuint format,FXuint opts=0); /// Destructor ~GMTrackDatabase(); }; #endif gogglesmm-0.12.7/src/GMFilename.h0000644000175000001440000000631711525430601015215 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMFILENAME_H #define GMFILENAME_H extern const FXchar * gmcodecnames[]; namespace GMFilename { enum { NOSPACES = 0x00000001, LOWERCASE = 0x00000002, LOWERCASE_EXTENSION = 0x00000004 }; enum { ENCODING_ASCII=0, ENCODING_UTF8, ENCODING_8859_1, ENCODING_8859_2, ENCODING_8859_3, ENCODING_8859_4, ENCODING_8859_5, ENCODING_8859_6, ENCODING_8859_7, ENCODING_8859_8, ENCODING_8859_9, ENCODING_8859_10, ENCODING_8859_11, ENCODING_8859_13, ENCODING_8859_14, ENCODING_8859_15, ENCODING_8859_16, ENCODING_CP437, ENCODING_CP850, ENCODING_CP852, ENCODING_CP855, ENCODING_CP856, ENCODING_CP857, ENCODING_CP860, ENCODING_CP861, ENCODING_CP862, ENCODING_CP863, ENCODING_CP864, ENCODING_CP865, ENCODING_CP866, ENCODING_CP869, ENCODING_CP874, ENCODING_CP1250, ENCODING_CP1251, ENCODING_CP1252, ENCODING_CP1253, ENCODING_CP1254, ENCODING_CP1255, ENCODING_CP1256, ENCODING_CP1257, ENCODING_CP1258, ENCODING_KOIR8, ENCODING_LAST }; /// Return FXTextCodec for given codec number FXTextCodec * findcodec(const FXuint & codec); /// Create Filename based on Track Information and Format String FXbool create(FXString & result,const GMTrack & track, const FXString & format,const FXString & forbidden,const FXuint & options,FXTextCodec * codec=NULL); FXString format_track(const GMTrack & track,const FXString & path,const FXString & forbidden,const FXuint & options,FXTextCodec * textcodec); enum { REPLACE_UNDERSCORE = 0x1, OVERWRITE = 0x2 }; /// Extract info from filename based on mask and store in GMTrack. void parse(GMTrack & track,const FXString & mask,FXuint opts); } #endif gogglesmm-0.12.7/src/ap_buffer.h0000644000175000001440000000431111667274256015215 0ustar sxjusers#ifndef AP_MEMORY_BUFFER_H #define AP_MEMORY_BUFFER_H namespace ap { class MemoryBuffer { protected: FXchar * buffer; FXival buffersize; FXchar * rdptr; FXchar * wrptr; public: // Constructor MemoryBuffer(FXival cap=4096); // Construct initialized from other buffer MemoryBuffer(const MemoryBuffer &); // Assignment operator MemoryBuffer& operator=(const MemoryBuffer&); // Append operator MemoryBuffer& operator+=(const MemoryBuffer&); // Adopt from buffer void adopt(MemoryBuffer &); // Make room for nbytes void reserve(FXival nbytes); // Clear buffer and reset to nbytes void reset(FXival nbytes=4096); // Clear buffer void clear(); // Number of unread bytes FXival size() const { return (wrptr-rdptr); } // Number of bytes that can be written FXival space() const { return buffersize - (wrptr-buffer); } // Size of the buffer FXival capacity() const { return buffersize; } // Read nbytes FXival read(void * bytes,FXival nbytes); // Read nbytes without advancing the read ptr. FXival peek(void * bytes,FXival nbytes); // Append bytes of nbytes. void append(const void * bytes,FXival nbytes); // Append constant nbytes. void append(const FXchar c, FXival nbytes=1); // Wrote nbytes. Updates the wrptr void wroteBytes(FXival nbytes); // Read nbytes. Update the rdptr void readBytes(FXival nbytes); /// Trim nbytes at beginning void trimBegin(FXival nbytes); /// Trim nbytes at end void trimEnd(FXival nbytes); /// Index into array const FXchar& operator[](FXint i) const { return rdptr[i]; } /// Return write pointer FXuchar* ptr() { return (FXuchar*)wrptr; } const FXuchar* ptr() const { return (FXuchar*)wrptr; } FXfloat * flt() { return reinterpret_cast(wrptr); } FXchar * s8() { return reinterpret_cast(wrptr); } FXshort * s16() { return reinterpret_cast(wrptr); } FXint * s32() { return reinterpret_cast(wrptr); } /// Return pointer to buffer FXuchar* data() { return (FXuchar*)rdptr; } const FXuchar* data() const { return (const FXuchar*)rdptr; } void setReadPosition(const FXuchar *p) { rdptr=(FXchar*)p; } // Destructor ~MemoryBuffer(); }; } #endif gogglesmm-0.12.7/src/ap_xml_parser.h0000644000175000001440000000126211667275702016117 0ustar sxjusers#ifndef AP_XML_PARSER_H #define AP_XML_PARSER_H namespace ap { class XMLStream { protected: void * parser; FXint depth; FXint skip; private: static void xml_element_start(void*,const FXchar*,const FXchar**); static void xml_element_end(void*,const FXchar*); static void xml_element_data(void*,const FXchar*,FXint); protected: virtual FXint begin(const FXchar *,const FXchar**) { return 1;} virtual void data(const FXchar *,FXint) {} virtual void end(const FXchar *){} void xml_print_error(); public: XMLStream(); FXbool parse(const FXchar * buffer,FXint length); FXbool parse(const FXString & buffer); virtual ~XMLStream(); }; } #endif gogglesmm-0.12.7/src/GMAbout.cpp0000644000175000001440000001316611525430601015102 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMAbout.h" #include "icons.h" #include #ifdef HAVE_DBUS #include "GMDBus.h" #endif #include #include #include #define UTF8_COPYRIGHT_SIGN "\xc2\xa9" #define APPLICATION_TITLE "Goggles Music Manager" // Object implementation FXIMPLEMENT(GMAboutDialog,FXDialogBox,NULL,0) GMAboutDialog::GMAboutDialog(FXApp * app) : FXDialogBox(app,FXString::null,DECOR_ALL,0,0,0,0,0,0,0,0,0,0) { setup(); } GMAboutDialog::GMAboutDialog(FXWindow* owner) : FXDialogBox(owner,FXString::null,DECOR_TITLE|DECOR_BORDER,0,0,0,0,0,0,0,0,0,0) { setup(); } GMAboutDialog::~GMAboutDialog(){ } void GMAboutDialog::setup(){ setTitle("About " APPLICATION_TITLE); logo = new FXPNGIcon(getApp(),about_png); logo->blend(FXRGB(255,255,255)); #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getApp()->getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getApp()->getNormalFont()->getFontDesc(); #endif fontdescription.size += 10; fontdescription.weight = FXFont::Bold; titlefont = new FXFont(getApp(),fontdescription); titlefont->create(); #if FOXVERSION < FXVERSION(1,7,17) getApp()->getNormalFont()->getFontDesc(fontdescription); #else fontdescription = getApp()->getNormalFont()->getFontDesc(); #endif fontdescription.size -= 10; licensefont = new FXFont(getApp(),fontdescription); licensefont->create(); FXLabel * label = new FXLabel(this,APPLICATION_TITLE,logo,ICON_ABOVE_TEXT|LAYOUT_CENTER_X|JUSTIFY_CENTER_X|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); label->setFont(titlefont); label->setBackColor(FXRGB(255,255,255)); label->setTextColor(FXRGB(0,0,0)); const FXchar gpl[] = "This program is free software: you can\n" "redistribute it and/or modify it under the\n" "terms of the GNU General Public License\n" "as published by the Free Software Foundation,\n" "either version 3 of the License, or (at your\n" "option) any later version."; label = new FXLabel(this,"v"APPLICATION_VERSION_STRING,NULL,LAYOUT_CENTER_X|LAYOUT_FILL_X,0,0,0,0,5,5,0,5); label->setBackColor(FXRGB(255,255,255)); label->setTextColor(FXRGB(0,0,0)); label = new FXLabel(this,"Copyright " UTF8_COPYRIGHT_SIGN " 2004-2011 Sander Jansen",NULL,LAYOUT_CENTER_X|LAYOUT_FILL_X,0,0,0,0,5,5,0,0); label->setBackColor(FXRGB(255,255,255)); label->setTextColor(FXRGB(0,0,0)); label = new FXLabel(this,gpl,NULL,LAYOUT_CENTER_X|LAYOUT_FILL_X,0,0,0,0,5,5,5,0); label->setBackColor(FXRGB(255,255,255)); label->setTextColor(FXRGB(0,0,0)); label->setFont(licensefont); FXString libraries; XML_Expat_Version expatversion = XML_ExpatVersionInfo(); FXint xineversion[3]; xine_get_version(&xineversion[0],&xineversion[1],&xineversion[2]); #ifdef HAVE_DBUS libraries.format("Build with FOX %d.%d.%d, Xine %d.%d.%d,\nSQLite %s, DBus %s, Expat %d.%d.%d\nand Taglib",fxversion[0],fxversion[1],fxversion[2],xineversion[0],xineversion[1],xineversion[2],sqlite3_libversion(),GMDBus::dbusversion().text(),expatversion.major,expatversion.minor,expatversion.micro); #else libraries.format("Build with FOX %d.%d.%d, Xine %d.%d.%d,\nSQLite %s, Expat %d.%d.%d and Taglib",fxversion[0],fxversion[1],fxversion[2],xineversion[0],xineversion[1],xineversion[2],sqlite3_libversion(),expatversion.major,expatversion.minor,expatversion.micro); #endif #if defined(TAGLIB_WITH_ASF) && (TAGLIB_WITH_ASF==1) #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) libraries.append(" (ASF/MP4)."); #else libraries.append(" (ASF)."); #endif #elif defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) libraries.append(" (MP4)."); #else libraries.append("."); #endif label = new FXLabel(this,libraries,NULL,LAYOUT_CENTER_X|LAYOUT_FILL_X,0,0,0,0,5,5,5,5); label->setBackColor(FXRGB(255,255,255)); label->setTextColor(FXRGB(0,0,0)); label->setFont(licensefont); new FXSeparator(this,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_BOTTOM|LAYOUT_FILL_X,0,0,0,0); new GMButton(closebox,tr("&Close"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_CENTER_X|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); } gogglesmm-0.12.7/src/GMList.cpp0000644000175000001440000003522411525430601014742 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMApp.h" #include "GMList.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMTrackList.h" #include "GMTrackView.h" #define ICON_SPACING 4 // Spacing between icon and label #define SIDE_SPACING 6 // Left or right spacing between items #define LINE_SPACING 4 // Line spacing between items static inline FXbool begins_with_keyword(const FXString & t){ for (FXint i=0;igetPreferences().gui_sort_keywords.no();i++){ if (comparecase(t,GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i],GMPlayerManager::instance()->getPreferences().gui_sort_keywords[i].length())==0) return TRUE; } return FALSE; } FXint genre_list_sort(const FXListItem* pa,const FXListItem* pb){ return comparecase(pa->getText(),pb->getText()); } FXint genre_list_sort_reverse(const FXListItem* pa,const FXListItem* pb){ return -comparecase(pa->getText(),pb->getText()); } FXint artist_list_sort(const FXListItem* pa,const FXListItem* pb){ register FXint a=0,b=0; if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return comparecase(&pa->getText()[a],&pb->getText()[b]); } FXint artist_list_sort_reverse(const FXListItem* pa,const FXListItem* pb){ register FXint a=0,b=0; if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return comparecase(&pb->getText()[b],&pa->getText()[a]); } FXint album_list_sort(const FXListItem* pa,const FXListItem* pb){ register FXint a=0,b=0; const GMAlbumListItem * sa = (GMAlbumListItem*)pa; const GMAlbumListItem * sb = (GMAlbumListItem*)pb; if (GMTrackView::album_by_year) { if (sa->year>sb->year) return 1; else if (sa->yearyear) return -1; } if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return comparecase(&pa->getText()[a],&pb->getText()[b]); } FXint album_list_sort_reverse(const FXListItem* pa,const FXListItem* pb){ register FXint a=0,b=0; const GMAlbumListItem * sa = (GMAlbumListItem*)pa; const GMAlbumListItem * sb = (GMAlbumListItem*)pb; if (GMTrackView::album_by_year) { if (sa->year>sb->year) return -1; else if (sa->yearyear) return 1; } if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return -comparecase(&pa->getText()[a],&pb->getText()[b]); } FXint source_list_sort(const FXTreeItem* pa,const FXTreeItem* pb){ const GMSource * const sa = (const GMSource*)pa->getData(); const GMSource * const sb = (const GMSource*)pb->getData(); if (sa->getType()>sb->getType()) return 1; else if (sa->getType()getType()) return -1; register FXint a=0,b=0; if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return compareversion(&pa->getText()[a],&pb->getText()[b]); } FXint source_list_sort_reverse(const FXTreeItem* pa,const FXTreeItem* pb){ const GMSource * const sa = (const GMSource*)pa->getData(); const GMSource * const sb = (const GMSource*)pb->getData(); if (sa->getType()>sb->getType()) return 1; else if (sa->getType()getType()) return -1; register FXint a=0,b=0; if (begins_with_keyword(pa->getText())) a=FXMIN(pa->getText().length()-1,pa->getText().find(' ')+1); if (begins_with_keyword(pb->getText())) b=FXMIN(pb->getText().length()-1,pb->getText().find(' ')+1); return -compareversion(&pa->getText()[a],&pb->getText()[b]); } // Object implementation FXIMPLEMENT(GMListItem,FXListItem,NULL,0) // Object implementation FXIMPLEMENT(GMAlbumListItem,GMListItem,NULL,0) // Draw item void GMListItem::draw(const GMList* list,FXDC& dc,FXint xx,FXint yy,FXint ww,FXint hh) const { register FXFont *font=list->getFont(); register FXint ih=0,th=0; if(icon) ih=icon->getHeight(); if(!label.empty()) th=font->getFontHeight(); if(isSelected()) dc.setForeground(list->getSelBackColor()); // else // dc.setForeground(list->getBackColor()); // FIXME maybe paint background in onPaint? dc.fillRectangle(xx,yy,ww,hh); if(hasFocus()){ dc.drawFocusRectangle(xx+1,yy+1,ww-2,hh-2); } xx+=SIDE_SPACING/2; if(icon){ dc.drawIcon(icon,xx,yy+(hh-ih)/2); xx+=ICON_SPACING+icon->getWidth(); } if(!label.empty()){ if(!isEnabled()) dc.setForeground(makeShadowColor(list->getBackColor())); else if(isSelected()) dc.setForeground(list->getSelTextColor()); else dc.setForeground(list->getTextColor()); dc.drawText(xx,yy+(hh-th)/2+font->getFontAscent(),label); } } // Map FXDEFMAP(GMList) GMListMap[]={ FXMAPFUNC(SEL_PAINT,0,GMList::onPaint), }; // Object implementation FXIMPLEMENT(GMList,FXList,GMListMap,ARRAYNUMBER(GMListMap)) // List GMList::GMList(){ rowcolor=FXRGB(255,255,255); } GMList::GMList(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h) : FXList(p,tgt,sel,opts,x,y,w,h) { rowcolor=GMPlayerManager::instance()->getPreferences().gui_row_color; thickfont=font; delete vertical; delete horizontal; delete corner; vertical=new GMScrollBar(this,this,GMList::ID_VSCROLLED,SCROLLBAR_VERTICAL); horizontal=new GMScrollBar(this,this,GMList::ID_HSCROLLED,SCROLLBAR_HORIZONTAL); corner=new GMScrollCorner(this); } GMList::~GMList(){ } // Create custom item FXListItem *GMList::createItem(const FXString& text,FXIcon* icon,void* ptr){ return new GMListItem(text,icon,ptr); } // Draw item list long GMList::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXDCWindow dc(this,event); FXint i,y,h; // Set font dc.setFont(font); // Paint items y=pos_y; for(i=0; igetHeight(this); if(event->rect.y<=y+h && yrect.y+event->rect.h){ if (i%2) dc.setForeground(rowcolor); else dc.setForeground(backColor); if (items[i]->getData()==(void*)(FXival)-1) dc.setFont(thickfont); else dc.setFont(font); #if FOXVERSION < FXVERSION(1,7,0) ((GMListItem*)items[i])->draw(this,dc,pos_x,y,FXMAX(listWidth,viewport_w),h); #else ((GMListItem*)items[i])->draw(this,dc,pos_x,y,FXMAX(listWidth,getVisibleWidth()),h); #endif } y+=h; } // Paint blank area below items if(yrect.y+event->rect.h){ dc.setForeground(backColor); dc.fillRectangle(event->rect.x,y,event->rect.w,event->rect.y+event->rect.h-y); } return 1; } // Object implementation FXIMPLEMENT(GMTreeItem,FXTreeItem,NULL,0) GMTreeItem::GMTreeItem(){ } // Get item height FXint GMTreeItem::getHeight(const FXTreeList* list) const { register FXFont *font=list->getFont(); register FXint th=0,oih=0,cih=0; if(openIcon) oih=openIcon->getHeight(); if(closedIcon) cih=closedIcon->getHeight(); if(!label.empty()) th=font->getFontHeight(); // if (oih>16) oih+=4; // if (cih>16) cih+=4; return FXMAX3(th,oih,cih)+4; } // Draw item void GMTreeItem::draw(const FXTreeList* list,FXDC& dc,FXint xx,FXint yy,FXint /* ww*/,FXint hh) const { register FXIcon *icon=(state&OPENED)?openIcon:closedIcon; register FXFont *font=list->getFont(); register FXint th=0,tw=0,ih=0,iw=0;//ox=xx,oy=yy; xx+=SIDE_SPACING/2; if(icon){ iw=icon->getWidth(); ih=icon->getHeight(); dc.drawIcon(icon,xx,yy+(hh-ih)/2); xx+=ICON_SPACING+iw; } if(!label.empty()){ tw=4+font->getTextWidth(label.text(),label.length()); th=4+font->getFontHeight(); yy+=(hh-th)/2; // if(isSelected()){ // dc.setForeground(list->getSelBackColor()); // dc.fillRectangle(xx,yy,tw,th); // dc.fillRectangle(ox,oy,ww,hh); // } if(hasFocus()){ dc.drawFocusRectangle(xx+1,yy+1,tw-2,th-2); } if(!isEnabled()) dc.setForeground(makeShadowColor(list->getBackColor())); else if(isSelected()) dc.setForeground(list->getSelTextColor()); else dc.setForeground(list->getTextColor()); dc.drawText(xx+2,yy+font->getFontAscent()+2,label); } } #define DEFAULT_INDENT 8 // Indent between parent and child #define HALFBOX_SIZE 4 // Half box size #define BOX_FUDGE 3 // Fudge border around box // Map FXDEFMAP(GMTreeList) GMTreeListMap[]={ FXMAPFUNC(SEL_PAINT,0,GMTreeList::onPaint) }; // Object implementation FXIMPLEMENT(GMTreeList,FXTreeList,GMTreeListMap,ARRAYNUMBER(GMTreeListMap)) GMTreeList::GMTreeList(){ } /// Construct a new, initially empty tree list GMTreeList::GMTreeList(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h) : FXTreeList(p,tgt,sel,opts,x,y,w,h) { rowcolor=GMPlayerManager::instance()->getPreferences().gui_row_color; GMScrollArea::replaceScrollbars(this); } FXTreeItem* GMTreeList::createItem(const FXString& text,FXIcon* oi,FXIcon* ci,void* ptr) { return (FXTreeItem*)new GMTreeItem(text,oi,ci,ptr); } // Draw item list long GMTreeList::onPaint(FXObject*,FXSelector,void* ptr){ FXEvent* event=(FXEvent*)ptr; FXTreeItem* item=firstitem; FXTreeItem* p; FXint yh,xh,x,y,w,h,xp,hh,cc=0; FXDCWindow dc(this,event); dc.setFont(font); x=pos_x; y=pos_y; if(options&TREELIST_ROOT_BOXES) x+=(4+indent); while(item && yrect.y+event->rect.h){ w=item->getWidth(this); h=item->getHeight(this); cc++; if(event->rect.y<=y+h){ // Draw item dc.setForeground(backColor); dc.fillRectangle(0,y,width,h); if (!item->isSelected()) { if (cc%2) { // dc.setForeground(backColor); // dc.fillRectangle(0,y,x+2,h); dc.setForeground(rowcolor); dc.fillRectangle(x,y,width-x,h); // dc.fillRectangle(x+2,y,width-x-2,h); } else { dc.setForeground(backColor); dc.fillRectangle(0,y,width,h); } } else { // dc.setForeground(backColor); // dc.fillRectangle(0,y,x+2,h); dc.setForeground(getSelBackColor()); // dc.fillRectangle(x+2,y,width-x-2,h); dc.fillRectangle(x,y,width-x,h); } ((GMTreeItem*)item)->draw(this,dc,x,y,w,h); // Show other paraphernalia such as dotted lines and expand-boxes if((options&(TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES)) && (((GMTreeItem*)item)->parent || (options&TREELIST_ROOT_BOXES))){ hh=h/2; yh=y+hh; xh=x-indent+(SIDE_SPACING/2); dc.setForeground(lineColor); dc.setBackground(backColor); dc.setStipple(STIPPLE_GRAY,pos_x&1,pos_y&1); if(options&TREELIST_SHOWS_LINES){ // Connect items with lines p=((GMTreeItem*)item)->parent; xp=xh; dc.setFillStyle(FILL_OPAQUESTIPPLED); while(p){ xp-=(indent+p->getHeight(this)/2); if(((GMTreeItem*)p)->next) dc.fillRectangle(xp,y,1,h); p=((GMTreeItem*)p)->parent; } if((options&TREELIST_SHOWS_BOXES) && (item->hasItems() || item->getFirst())){ if(((GMTreeItem*)item)->prev || ((GMTreeItem*)item)->parent) dc.fillRectangle(xh,y,1,yh-y-HALFBOX_SIZE); if(((GMTreeItem*)item)->next) dc.fillRectangle(xh,yh+HALFBOX_SIZE,1,y+h-yh-HALFBOX_SIZE); } else{ if(((GMTreeItem*)item)->prev || ((GMTreeItem*)item)->parent) dc.fillRectangle(xh,y,1,hh); if(((GMTreeItem*)item)->next) dc.fillRectangle(xh,yh,1,h); dc.fillRectangle(xh,yh,x+(SIDE_SPACING/2)-2-xh,1); } dc.setFillStyle(FILL_SOLID); } // Boxes before items for expand/collapse of item if((options&TREELIST_SHOWS_BOXES) && (item->hasItems() || item->getFirst())){ dc.setFillStyle(FILL_OPAQUESTIPPLED); dc.fillRectangle(xh+4,yh,(SIDE_SPACING/2)-2,1); dc.setFillStyle(FILL_SOLID); dc.drawRectangle(xh-HALFBOX_SIZE,yh-HALFBOX_SIZE,HALFBOX_SIZE+HALFBOX_SIZE,HALFBOX_SIZE+HALFBOX_SIZE); dc.setForeground(textColor); dc.fillRectangle(xh-HALFBOX_SIZE+2,yh,HALFBOX_SIZE+HALFBOX_SIZE-3,1); if(!(options&TREELIST_AUTOSELECT) && !item->isExpanded()){ dc.fillRectangle(xh,yh-HALFBOX_SIZE+2,1,HALFBOX_SIZE+HALFBOX_SIZE-3); } } } } y+=h; // Move on to the next item if(((GMTreeItem*)item)->first && ((options&TREELIST_AUTOSELECT) || ((GMTreeItem*)item)->isExpanded())){ x+=(indent+h/2); item=((GMTreeItem*)item)->first; continue; } while(!((GMTreeItem*)item)->next && ((GMTreeItem*)item)->parent){ item=((GMTreeItem*)item)->parent; x-=(indent+item->getHeight(this)/2); } item=((GMTreeItem*)item)->next; } if(yrect.y+event->rect.h){ dc.setForeground(backColor); dc.fillRectangle(event->rect.x,y,event->rect.w,event->rect.y+event->rect.h-y); } return 1; } gogglesmm-0.12.7/src/GMTag.h0000644000175000001440000001041411533035043014201 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTAG_H #define GMTAG_H /// Album number consists of a disc number + track number #define GMALBUMNO(disc,track) ((((FX::FXuint)(track))&0xffff) | (((FX::FXuint)(disc))<<16)) /// Get the disc number from a album no. #define GMDISCNO(s) ((FX::FXushort)(((s)>>16)&0xffff)) /// Get the track number from a album no. #define GMTRACKNO(s) ((FX::FXushort)((s)&0xffff)) class GMTrack{ public: FXString path; FXString mrl; FXString title; FXString artist; FXString album; FXString album_artist; FXString genre; FXint year; FXint no; FXint time; FXint bitrate; FXdouble album_gain; FXdouble album_peak; FXdouble track_gain; FXdouble track_peak; public: GMTrack(); /// Get track number FXushort getTrackNumber() const { return (FXushort)(no&0xffff); } /// Set Track Number void setTrackNumber(FXushort track) { no|=((FXuint)track)&0xffff; } /// Set Disc Number void setDiscNumber(FXushort disc) { no|=((FXuint)disc)<<16; } /// Get disc number FXushort getDiscNumber() const { return (FXushort)(no>>16); } /// Load from tag in given filename. Note that mrl is not set FXbool loadTag(const FXString & filename); /// Save to tag in given filename. Note that mrl is not set FXbool saveTag(const FXString & filename,FXuint opts=0); FXbool loadPath(const FXString & mrl); static FXbool fromPath(const FXString & mrl,GMTrack & track); void clear(); }; class GMCover; typedef FXArray GMCoverList; class GMCover { public: enum { Other = 0, FileIcon = 1, OtherFileIcon = 2, FrontCover = 3, BackCover = 4, Leaflet = 5, Media = 6, LeadArtist = 7, Artist = 8, Conductor = 9, Band = 10, Composer = 11, Lyricist = 12, RecordingLocation = 13, DuringRecoding = 14, DuringPerformance = 15, ScreenCapture = 16, Fish = 17, Illustration = 18, BandLogo = 19, PublisherLogo = 20 }; public: FXImage * image; FXString description; FXuint type; public: GMCover(); GMCover(FXImage * img,FXuint t=GMCover::Other,const FXString & label=FXString::null); ~GMCover(); public: static FXint fromTag(const FXString & mrl,GMCoverList & list,FXint scale=0); static FXint fromPath(const FXString & mrl,GMCoverList & list,FXint scale=0); static GMCover * fromTag(const FXString & mrl,FXint scale=0); static GMCover * fromPath(const FXString & mrl,FXint scale=0); static FXImage * toImage(GMCover*); static FXIcon * toIcon(GMCover*); }; namespace GMTag { struct Properties { FXint bitrate; FXint samplerate; FXint channels; }; void init(); FXbool properties(const FXString & mrl,Properties & p); FXbool length(GMTrack & info); } #endif gogglesmm-0.12.7/src/GMThread.cpp0000644000175000001440000000331011525430601015225 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMThread.h" GMThread::GMThread(FXObject*tgt) : feedback(FXApp::instance()),target(tgt),running(TRUE){ } GMThread::~GMThread(){ } void GMThread::dispose_and_join(){ dispose(); join(); } void GMThread::dispose() { running=FALSE; } gogglesmm-0.12.7/src/GMApp.cpp0000644000175000001440000003347711553121174014562 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include "gmdefs.h" #include "GMApp.h" #include "GMList.h" #include "GMTrackDatabase.h" #include "GMTrackList.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMClipboard.h" #include "GMTrayIcon.h" #include "icons.h" #ifdef HAVE_NLS #define PACKAGE "gogglesmm" #ifndef LOCALEDIR #error LOCALEDIR needs to be defined!! #endif #include #include class GMTranslator : public FXTranslator { FXDECLARE(GMTranslator) private: private: GMTranslator(const GMTranslator&); GMTranslator &operator=(const GMTranslator&); #if FOXVERSION < FXVERSION(1,7,16) protected: GMTranslator(){} public: /// Construct translator GMTranslator(FXApp* a): FXTranslator(a) { setlocale(LC_MESSAGES,""); setlocale(LC_NUMERIC,"C"); bindtextdomain(PACKAGE,LOCALEDIR); bind_textdomain_codeset(PACKAGE,"UTF-8"); textdomain(PACKAGE); #ifdef DEBUG fxmessage("localedir: %s\n",LOCALEDIR); #endif }; #else public: GMTranslator(){ setlocale(LC_MESSAGES,""); setlocale(LC_NUMERIC,"C"); bindtextdomain(PACKAGE,LOCALEDIR); bind_textdomain_codeset(PACKAGE,"UTF-8"); textdomain(PACKAGE); #ifdef DEBUG fxmessage("localedir: %s\n",LOCALEDIR); #endif }; #endif #if FOXVERSION < FXVERSION(1,7,16) virtual const FXchar* tr(const FXchar* context,const FXchar* message,const FXchar* hint=NULL) const; #else virtual const FXchar* tr(const FXchar* context,const FXchar* message,const FXchar* hint=NULL,FXint count=-1) const; #endif ~GMTranslator() { } }; FXIMPLEMENT(GMTranslator,FXTranslator,NULL,0) #if FOXVERSION < FXVERSION(1,7,16) const FXchar* GMTranslator::tr(const FXchar*,const FXchar* message,const FXchar*) const { return gettext(message); } #else const FXchar* GMTranslator::tr(const FXchar*,const FXchar* message,const FXchar*,FXint) const { return gettext(message); } #endif #endif extern const FXchar * fxtr(const FXchar *x){ #ifdef HAVE_NLS return FXApp::instance()->getTranslator()->tr(NULL,x); #else return x; #endif } FXIMPLEMENT(GMApp,FXApp,NULL,0) GMApp* GMApp::instance() { return dynamic_cast(FXApp::instance()); } GMApp::GMApp(const FXString& name,const FXString& vendor) : FXApp(name,vendor){ clipboard = new GMClipboard(this); xembed=0; } GMApp::~GMApp(){ delete clipboard; } FXString GMApp::getCacheDirectory(FXbool create) { FXString xdg_cache_home = FXSystem::getEnvironment("XDG_CACHE_HOME"); if (xdg_cache_home.empty()) xdg_cache_home=FXSystem::getHomeDirectory()+PATHSEPSTRING ".cache" ; xdg_cache_home+=PATHSEPSTRING "gogglesmm"; if (create) gm_make_path(xdg_cache_home); return xdg_cache_home; } void GMApp::create() { FXString systemtray = GMStringFormat("_NET_SYSTEM_TRAY_S%d",DefaultScreen((Display*)getDisplay())); xembed = (FXID)XInternAtom((Display*)getDisplay(),"_XEMBED",False); xmanager = (FXID)XInternAtom((Display*)getDisplay(),"MANAGER",True); xsystemtray = (FXID)XInternAtom((Display*)getDisplay(),systemtray.text(),True); FXApp::create(); #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getNormalFont()->getFontDesc(); #endif fontdescription.weight = FXFont::Bold; thickfont = new FXFont(this,fontdescription); thickfont->create(); XSelectInput((Display*)getDisplay(),getRootWindow()->id(),KeyPressMask|KeyReleaseMask|StructureNotifyMask); } void GMApp::setFont(const FXFontDesc & fnt){ getNormalFont()->destroy(); getNormalFont()->setFontDesc(fnt); getNormalFont()->create(); reg().writeStringEntry("SETTINGS","normalfont",getNormalFont()->getFont().text()); #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getNormalFont()->getFontDesc(); #endif fontdescription.weight = FXFont::Bold; thickfont->destroy(); thickfont->setFontDesc(fontdescription); thickfont->create(); } void GMApp::updateFont() { #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getNormalFont()->getFontDesc(); #endif setFont(fontdescription); } #if FOXVERSION < FXVERSION(1,7,0) void GMApp::init(int& argc,char** argv,bool connect) { #else void GMApp::init(int& argc,char** argv,FXbool connect) { #endif FXApp::init(argc,argv,connect); #ifdef HAVE_NLS #if FOXVERSION < FXVERSION(1,7,16) setTranslator(new GMTranslator(this)); #else setTranslator(new GMTranslator()); #endif #endif } enum { XEMBED_EMBEDDED_NOTIFY = 0, XEMBED_MODALITY_ON = 10, XEMBED_MODALITY_OFF = 11, XEMBED_REQUEST_FOCUS = 3 }; #include // Get keysym; interprets the modifiers! static FXuint keysym(FXRawEvent& event){ KeySym sym=KEY_VoidSymbol; char buffer[40]; XLookupString(&event.xkey,buffer,sizeof(buffer),&sym,NULL); return sym; } #if FOXVERSION < FXVERSION(1,7,0) bool GMApp::dispatchEvent(FXRawEvent & ev) { #else FXbool GMApp::dispatchEvent(FXRawEvent & ev) { #endif /// Handle Global Hotkeys if (ev.xany.window==getRootWindow()->id()){ if (ev.xany.type==KeyPress) { //fxmessage("keypress %d %x\n",ev.xkey.keycode,keysym(ev)); if (GMPlayerManager::instance()->handle_global_hotkeys(keysym(ev))) return true; } else if (ev.xany.type==ClientMessage) { if ((Atom)ev.xclient.message_type==(Atom)xmanager && (Atom)ev.xclient.data.l[1]==(Atom)xsystemtray) { if (GMPlayerManager::instance()->getTrayIcon()) GMPlayerManager::instance()->getTrayIcon()->dock(); return true; } } } FXWindow * window = findWindowWithId(ev.xany.window); if (window && ev.xany.type==ClientMessage && ev.xclient.message_type==xembed) { switch(ev.xclient.data.l[1]) { case XEMBED_EMBEDDED_NOTIFY: window->tryHandle(this,FXSEL(SEL_EMBED_NOTIFY,0),(void*)(FXival)ev.xclient.data.l[3]); break; case XEMBED_MODALITY_ON : window->tryHandle(this,FXSEL(SEL_EMBED_MODAL_ON,0),NULL); break; case XEMBED_MODALITY_OFF : window->tryHandle(this,FXSEL(SEL_EMBED_MODAL_OFF,0),NULL); break; default : /*fxmessage("Missed a message %d\n",ev.xclient.data.l[1]);*/ break; } return true; } return FXApp::dispatchEvent(ev); } FXDEFMAP(GMPlug) GMPlugMap[]={ FXMAPFUNC(SEL_EMBED_NOTIFY,0,GMPlug::onEmbedded) }; FXIMPLEMENT(GMPlug,FXTopWindow,GMPlugMap,ARRAYNUMBER(GMPlugMap)); GMPlug::GMPlug(){ } GMPlug::GMPlug(FXApp * app) : FXTopWindow(app,"test",NULL,NULL,DECOR_NONE,0,0,1,1,0,0,0,0,0,0) , socket(0) { } GMPlug::~GMPlug(){ } #if FOXVERSION < FXVERSION(1,7,0) bool GMPlug::doesOverrideRedirect() const { return true; } #else FXbool GMPlug::doesOverrideRedirect() const{ return true; } #endif void GMPlug::setFocus(){ FXShell::setFocus(); if (xid && socket) { XEvent ev; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = socket; ev.xclient.message_type = ((GMApp*)getApp())->xembed; ev.xclient.format = 32; ev.xclient.data.l[0] = CurrentTime; ev.xclient.data.l[1] = XEMBED_REQUEST_FOCUS; XSendEvent((Display*)getApp()->getDisplay(),socket, False, NoEventMask, &ev); } } void GMPlug::create() { FXTopWindow::create(); if (xid) { Atom xembedinfo = XInternAtom((Display*)getApp()->getDisplay(),"_XEMBED_INFO",0); if (xembedinfo!=None) { unsigned long info[2]={0,(1<<0)}; XChangeProperty((Display*)getApp()->getDisplay(),xid,xembedinfo,xembedinfo,32,PropModeReplace,(unsigned char*)info,2); } } } long GMPlug::onEmbedded(FXObject*,FXSelector,void*ptr){ flags|=FLAG_SHOWN; socket=(FXID)(FXival)ptr; return 1; } void ewmh_set_window_icon(const FXWindow * window,FXImage * icon) { #ifndef WIN32 Atom net_wm_icon = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_ICON",False); unsigned long * data=NULL; int nelems=2+(icon->getWidth()*icon->getHeight()); allocElms(data,nelems); data[0]=icon->getWidth(); data[1]=icon->getHeight(); for (FXint i=0;i<(icon->getWidth()*icon->getHeight());i++){ #if FOXVERSION < FXVERSION(1,7,26) const FXColor val = icon->getData()[i]; data[i+2]=FXRGBA(FXBLUEVAL(val),FXGREENVAL(val),FXREDVAL(val),FXALPHAVAL(val)); #else data[i+2]=icon->getData()[i]; #endif } /// Set Property XChangeProperty((Display*)window->getApp()->getDisplay(),window->id(),net_wm_icon,XA_CARDINAL,32,PropModeReplace,(unsigned char*)data,nelems); freeElms(data); #endif } void fix_wm_properties(const FXWindow * window) { #ifndef WIN32 XTextProperty textprop; #if FOXVERSION < FXVERSION(1,7,0) FXString host=FXURL::hostname(); #else FXString host=FXSystem::getHostName(); #endif /// set the name of the machine on which this application is running textprop.value = (unsigned char *)host.text(); textprop.encoding = XA_STRING; textprop.format = 8; textprop.nitems = host.length(); XSetWMClientMachine((Display*)window->getApp()->getDisplay(),window->id(), &textprop); /// Override class hints XClassHint hint; hint.res_name=(char*)"gogglesmm"; hint.res_class=(char*)"gogglesmm"; XSetClassHint((Display*)window->getApp()->getDisplay(),window->id(),&hint); #endif } void ewmh_change_window_type(const FXWindow * window,FXuint kind) { #ifndef WIN32 static Atom net_wm_window_type = None; static Atom net_wm_window_type_menu = None; static Atom net_wm_window_type_dropdown_menu = None; static Atom net_wm_window_type_popup_menu = None; static Atom net_wm_window_type_combo = None; static Atom net_wm_window_type_tooltip = None; static Atom net_wm_window_type_dialog = None; static Atom net_wm_window_type_normal = None; FXASSERT(window->getApp()); FXASSERT(window->getApp()->getDisplay()); FXASSERT(window->id()); if (net_wm_window_type==None){ net_wm_window_type = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE",False); net_wm_window_type_menu = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_MENU",False); net_wm_window_type_dropdown_menu = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",False); net_wm_window_type_popup_menu = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_POPUP_MENU",False); net_wm_window_type_combo = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_COMBO",False); net_wm_window_type_tooltip = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_TOOLTIP",False); net_wm_window_type_dialog = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_DIALOG",False); net_wm_window_type_normal = XInternAtom((Display*)window->getApp()->getDisplay(),"_NET_WM_WINDOW_TYPE_NORMAL",False); } unsigned int ntypes=0; Atom types[3]={0}; switch(kind) { case WINDOWTYPE_DIALOG : types[0]=net_wm_window_type_dialog; ntypes=1; break; case WINDOWTYPE_COMBO : types[0]=net_wm_window_type_combo; types[1]=net_wm_window_type_dropdown_menu; types[2]=net_wm_window_type_menu; ntypes=3; break; case WINDOWTYPE_POPUP_MENU : types[0]=net_wm_window_type_popup_menu; types[1]=net_wm_window_type_menu; ntypes=2; break; case WINDOWTYPE_DROPDOWN_MENU : types[0]=net_wm_window_type_dropdown_menu; types[1]=net_wm_window_type_menu; ntypes=2; break; case WINDOWTYPE_TOOLTIP : types[0]=net_wm_window_type_tooltip; ntypes=1; break; default : types[0]=net_wm_window_type_normal; ntypes=1; break; } /// Set Property XChangeProperty((Display*)window->getApp()->getDisplay(),window->id(),net_wm_window_type,XA_ATOM,32,PropModeReplace,(unsigned char*)&types,ntypes); #endif } gogglesmm-0.12.7/src/GMSourceView.cpp0000644000175000001440000002577111525430601016130 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include #include "GMApp.h" #include "GMList.h" #include "GMTrackList.h" #include "GMSourceView.h" #include "GMTrackView.h" #include "GMWindow.h" #include "GMSource.h" #include "GMDatabaseSource.h" #include "GMStreamSource.h" #include "GMPlayerManager.h" #include "GMIconTheme.h" FXDEFMAP(GMSourceView) GMSourceViewMap[]={ FXMAPFUNC(SEL_COMMAND,GMSourceView::ID_SOURCE_LIST_HEADER,GMSourceView::onCmdSortSourceList), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,GMSourceView::ID_SOURCE_LIST,GMSourceView::onSourceContextMenu), FXMAPFUNC(SEL_COMMAND,GMSourceView::ID_SOURCE_LIST,GMSourceView::onCmdSourceSelected), FXMAPFUNC(SEL_DND_MOTION,GMSourceView::ID_SOURCE_LIST,GMSourceView::onDndSourceMotion), FXMAPFUNC(SEL_DND_DROP,GMSourceView::ID_SOURCE_LIST,GMSourceView::onDndSourceDrop), FXMAPFUNC(SEL_COMMAND,GMSourceView::ID_NEW_PLAYLIST,GMSourceView::onCmdNewPlayList), FXMAPFUNC(SEL_UPDATE,GMSourceView::ID_NEW_PLAYLIST,GMSourceView::onUpdNewPlayList), FXMAPFUNC(SEL_COMMAND,GMSourceView::ID_NEW_STATION,GMSourceView::onCmdNewStation), FXMAPFUNC(SEL_COMMAND,GMSourceView::ID_EXPORT,GMSourceView::onCmdExport), FXMAPFUNC(SEL_UPDATE,GMSourceView::ID_EXPORT,GMSourceView::onUpdExport), }; FXIMPLEMENT(GMSourceView,GMScrollFrame,GMSourceViewMap,ARRAYNUMBER(GMSourceViewMap)) GMSourceView::GMSourceView() : source(NULL) { } GMSourceView::GMSourceView(FXComposite* p) : GMScrollFrame(p) , source(NULL) { sourcelistheader = new GMHeaderButton(this,tr("Sources\tPress to change sorting order\tPress to change sorting order"),NULL,this,ID_SOURCE_LIST_HEADER,LAYOUT_FILL_X|FRAME_THICK|FRAME_RAISED|JUSTIFY_LEFT); sourcelist = new GMTreeList(this,this,ID_SOURCE_LIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|TREELIST_BROWSESELECT); sourcelist->dropEnable(); sourcelist->setSortFunc(source_list_sort); sourcelistheader->setArrowState(ARROW_DOWN); updateColors(); } GMSourceView::~GMSourceView(){ } void GMSourceView::updateColors() { sourcelist->setRowColor(GMPlayerManager::instance()->getPreferences().gui_row_color); } void GMSourceView::updateSource(GMSource * src){ FXTreeItem * item = sourcelist->getFirstItem(); while(item) { if (item->getData()==src) { item->setText(tr(src->getName().text())); break; } item=item->getNext(); } resort(); } void GMSourceView::setSource(GMSource * src,FXbool makecurrent/*=true*/){ if (src!=source) { source=src; if (makecurrent) { FXTreeItem * item = sourcelist->getFirstItem(); while(item) { if (item->getData()==src) { sourcelist->setCurrentItem(item,false); break; } item=item->getNext(); } } GMPlayerManager::instance()->getTrackView()->setSource(source); } } void GMSourceView::clear() { sourcelist->clearItems(); } void GMSourceView::refresh() { clear(); listSources(); } void GMSourceView::init() { loadSettings("window"); clear(); listsources(); FXString key = getApp()->reg().readStringEntry("window","source-list-current",""); if (!key.empty()){ FXTreeItem * item = sourcelist->getFirstItem(); while(item) { GMSource * src = (GMSource*)item->getData(); if (src->settingKey()==key) { sourcelist->setCurrentItem(item); break; } item=item->getNext(); } } if (sourcelist->getCurrentItem()==NULL && sourcelist->getFirstItem()) sourcelist->setCurrentItem(sourcelist->getFirstItem()); source=(GMSource*)sourcelist->getItemData(sourcelist->getCurrentItem()); GMPlayerManager::instance()->getTrackView()->init(source); } void GMSourceView::resort() { sortSources(); } FXbool GMSourceView::listsources() { GMTreeItem * item=NULL; for (FXint i=0;igetNumSources();i++){ GMSource * source = GMPlayerManager::instance()->getSource(i); switch(source->getType()){ case SOURCE_DATABASE : item = new GMTreeItem(tr(source->getName().text()),GMIconTheme::instance()->icon_source_library,GMIconTheme::instance()->icon_source_library,source); break; case SOURCE_DATABASE_PLAYLIST: item = new GMTreeItem(tr(source->getName().text()),GMIconTheme::instance()->icon_source_playlist,GMIconTheme::instance()->icon_source_playlist,source); break; case SOURCE_INTERNET_RADIO : item = new GMTreeItem(tr(source->getName().text()),GMIconTheme::instance()->icon_source_internetradio,GMIconTheme::instance()->icon_source_internetradio,source); break; default : item = NULL; break; } if (item) { sourcelist->appendItem(NULL,item); } } sourcelist->sortItems(); return true; } FXbool GMSourceView::listSources() { listsources(); setSource((GMSource*)sourcelist->getItemData(sourcelist->getCurrentItem()),false); return true; } void GMSourceView::sortSources() const{ sourcelist->sortItems(); } void GMSourceView::loadSettings(const FXString & key) { FXbool sort_reverse,shown; sort_reverse = getApp()->reg().readBoolEntry(key.text(),"source-list-sort-reverse",false); if (sort_reverse) sourcelist->setSortFunc(source_list_sort_reverse); else sourcelist->setSortFunc(source_list_sort); shown = getApp()->reg().readBoolEntry(key.text(),"source-list",true); if (shown) getParent()->show(); else getParent()->hide(); } void GMSourceView::saveSettings(const FXString & key) const { getApp()->reg().writeBoolEntry(key.text(),"source-list-sort-reverse",sourcelist->getSortFunc()==source_list_sort_reverse); getApp()->reg().writeBoolEntry(key.text(),"source-list",getParent()->shown()); } void GMSourceView::saveView() const { saveSettings("window"); if (source) { getApp()->reg().writeStringEntry("window","source-list-current",source->settingKey().text()); } } long GMSourceView::onCmdSourceSelected(FXObject*,FXSelector,void*){ FXTreeItem * item = sourcelist->getCurrentItem(); if (item) { setSource((GMSource*)item->getData(),false); } return 1; } long GMSourceView::onCmdSortSourceList(FXObject*,FXSelector,void*){ if (sourcelist->getSortFunc()==source_list_sort) { sourcelist->setSortFunc(source_list_sort_reverse); sourcelistheader->setArrowState(ARROW_UP); } else { sourcelist->setSortFunc(source_list_sort); sourcelistheader->setArrowState(ARROW_DOWN); } sortSources(); return 1; } long GMSourceView::onSourceContextMenu(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (event->moved) return 0; GMTreeItem * item = dynamic_cast(sourcelist->getItemAt(event->win_x,event->win_y)); GMMenuPane pane(this); if (item) { GMSource * source = (GMSource*)item->getData(); if (source && source->source_context_menu(&pane)) { sourcelist->setCurrentItem(item); onCmdSourceSelected(NULL,0,NULL); // Simulate SEL_COMMAND } } else { new GMMenuCommand(&pane,tr("New Playlist…\t\tCreate a new playlist"),GMIconTheme::instance()->icon_playlist,this,ID_NEW_PLAYLIST); new GMMenuCommand(&pane,tr("Import Playlist…\t\tImport existing playlist"),GMIconTheme::instance()->icon_import,GMPlayerManager::instance()->getDatabaseSource(),GMDatabaseSource::ID_IMPORT_PLAYLIST); new GMMenuCommand(&pane,tr("New Radio Station…\t\tCreate a new playlist"),NULL,this,GMSourceView::ID_NEW_STATION); } pane.create(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x,event->root_y); getApp()->runPopup(&pane); return 1; } long GMSourceView::onDndSourceMotion(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); GMTreeItem * item = dynamic_cast(sourcelist->getItemAt(event->win_x,event->win_y)); if (item) { GMSource * source = reinterpret_cast(item->getData()); FXDragType*types; FXuint ntypes; if (sourcelist->inquireDNDTypes(FROM_DRAGNDROP,types,ntypes)){ if (source->dnd_source_accepts(types,ntypes)){ sourcedrop=source; sourcelist->acceptDrop(DRAG_LINK); freeElms(types); return 1; } freeElms(types); } } sourcedrop=NULL; return 0; } long GMSourceView::onDndSourceDrop(FXObject*sender,FXSelector,void*ptr){ if (sourcedrop) { long code = sourcedrop->handle(sender,FXSEL(SEL_DND_DROP,GMSource::ID_DROP),ptr); sourcedrop=NULL; return code; } return 0; } long GMSourceView::onCmdNewPlayList(FXObject*sender,FXSelector,void*ptr){ if (GMPlayerManager::instance()->getSource(0)) return GMPlayerManager::instance()->getSource(0)->handle(sender,FXSEL(SEL_COMMAND,GMDatabaseSource::ID_NEW_PLAYLIST),ptr); return 0; } long GMSourceView::onUpdNewPlayList(FXObject*sender,FXSelector,void*ptr){ if (GMPlayerManager::instance()->getSource(0)) return GMPlayerManager::instance()->getSource(0)->handle(sender,FXSEL(SEL_UPDATE,GMDatabaseSource::ID_NEW_PLAYLIST),ptr); return 0; } long GMSourceView::onCmdNewStation(FXObject*sender,FXSelector,void*ptr){ for (FXint i=0;igetNumSources();i++){ GMSource * source = GMPlayerManager::instance()->getSource(i); if (source->getType()==SOURCE_INTERNET_RADIO) return source->handle(sender,FXSEL(SEL_COMMAND,GMStreamSource::ID_NEW_STATION),ptr); } return 0; } long GMSourceView::onCmdExport(FXObject*sender,FXSelector,void*ptr){ if (source) return source->handle(sender,FXSEL(SEL_COMMAND,GMSource::ID_EXPORT),ptr); return 0; } long GMSourceView::onUpdExport(FXObject*sender,FXSelector,void*ptr){ if (source) return source->handle(sender,FXSEL(SEL_UPDATE,GMSource::ID_EXPORT),ptr); return 0; } gogglesmm-0.12.7/src/GMImageView.cpp0000644000175000001440000002053511615270075015712 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMImageView.h" #include #include // non power of two textures are currently broken in Mesa 7.10 in combination with mip mapping // fixed in Mesa 7.11-rc4 //#define DISABLE_TEXTURE_NON_POWER_OF_TWO 1 // Disable MIPMAP if needed //#define DISABLE_MIPMAP 1 FXDEFMAP(GMImageView) GMImageViewMap[]={ FXMAPFUNC(SEL_PAINT,0,GMImageView::onPaint) }; FXIMPLEMENT(GMImageView,FXGLCanvas,GMImageViewMap,ARRAYNUMBER(GMImageViewMap)); GMImageView::GMImageView(){ image_width=0; image_height=0; texture_id=0; } GMImageView::GMImageView(FXComposite* p,FXGLVisual *vis,FXuint opts,FXint x,FXint y,FXint w,FXint h) : FXGLCanvas(p,vis,NULL,0,opts,x,y,w,h){ image_width=0; image_height=0; texture_id=0; } GMImageView::~GMImageView(){ image_width=0; image_height=0; texture_id=0; } void GMImageView::updateTexture(FXImage * image) { FXint texture_max; if (!makeCurrent()) return; if (image) { image_width=image->getWidth(); image_height=image->getHeight(); /// Query Maximum Texture Size glGetIntegerv(GL_MAX_TEXTURE_SIZE,&texture_max); #ifndef DISABLE_TEXTURE_NON_POWER_OF_TWO /// Check if non power of two textures are supported. const GLubyte * extensions = glGetString(GL_EXTENSIONS); texture_power_of_two = (strstr((const char*)extensions,"GL_ARB_texture_non_power_of_two")==NULL); #else texture_power_of_two = true; #endif /// Prescale to maximum texture size if necessary if((image_width>texture_max) || (image_height>texture_max)){ if(image_width>image_height) image->scale(texture_max,(texture_max*image_height)/image_width,1); else image->scale((texture_max*image_width)/image_height,texture_max,1); image_width=image->getWidth(); image_height=image->getHeight(); } /// Get a nice texture size if (texture_power_of_two) { texture_width=1; texture_height=1; while(image_width>texture_width) texture_width<<=1; while(image_height>texture_height) texture_height<<=1; } else { texture_width=image_width; texture_height=image_height; } FXASSERT(texture_width<=texture_max); FXASSERT(texture_height<=texture_max); /// Generate a new texture if required. if (texture_id==0) { glGenTextures(1,&texture_id); } glBindTexture(GL_TEXTURE_2D,texture_id); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); #if defined(GL_VERSION_1_4) && !defined(DISABLE_MIPMAP) glHint(GL_GENERATE_MIPMAP_HINT,GL_NICEST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE); #else glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); #endif #if FOXVERSION < FXVERSION(1,7,26) if (texture_width==image_width && texture_height==image_height) { glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,texture_width,texture_height,0,GL_RGBA,GL_UNSIGNED_BYTE,image->getData()); } else { glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,texture_width,texture_height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,image_width,image_height,GL_RGBA,GL_UNSIGNED_BYTE,image->getData()); } #else if (texture_width==image_width && texture_height==image_height) { glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,texture_width,texture_height,0,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,image->getData()); } else { glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,texture_width,texture_height,0,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,NULL); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,image_width,image_height,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,image->getData()); } #endif } else { image_width=0; image_height=0; if (texture_id) { glDeleteTextures(1,&texture_id); texture_id=0; } } makeNonCurrent(); } void GMImageView::setImage(FXImage * img) { updateTexture(img); recalc(); update(); } FXint GMImageView::getDefaultWidth() const { return 256; } FXint GMImageView::getDefaultHeight() const { return 256; } // Repaint the GL window long GMImageView::onPaint(FXObject*,FXSelector,void*){ FXGLVisual *vis=(FXGLVisual*)getVisual(); FXfloat th=1.0f; FXfloat tw=1.0f; #if FOXVERSION < FXVERSION(1,7,0) FXVec4f background(backColor); #else FXVec4f background=colorToVec4f(backColor); #endif FXASSERT(xid); if(makeCurrent()){ glViewport(0,0,getWidth(),getHeight()); glClearColor(background.x,background.y,background.z,background.w); glClear(GL_COLOR_BUFFER_BIT); if (image_width && image_height) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluOrtho2D(0,getWidth(),getHeight(),0); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); glBindTexture(GL_TEXTURE_2D,texture_id); FXfloat scale = FXMIN(( width/(FXfloat)image_width),(height/(FXfloat)image_height)); FXint xmin=0,xmax=image_width*scale; FXint ymin=0,ymax=image_height*scale; xmin=(getWidth()-xmax)/2.0; ymin=(getHeight()-ymax)/2.0; xmax+=xmin; ymax+=ymin; if (texture_width!=image_width || texture_height!=image_height){ th = (1.0f / (FXfloat)(texture_height))*image_height; tw = (1.0f / (FXfloat)(texture_width))*image_width; } #ifndef GL_VERSION_1_1 FXint coords[8]={xmin,ymin, xmin,ymax, xmax,ymax, xmax,ymin}; FXfloat tex[8]={0.0f,0.0f, 0.0f,th, tw,th, tw,0.0f}; FXfloat colors[12]={background.x,background.y,background.z, background.x,background.y,background.z, background.x,background.y,background.z, background.x,background.y,background.z}; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2,GL_INT,0,coords); glColorPointer(3,GL_FLOAT,0,colors); glTexCoordPointer(2,GL_FLOAT,0,tex); glDrawArrays(GL_QUADS,0,4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); #else glColor4fv(background); glBegin(GL_QUADS); glTexCoord2f(0.0,0.0); glVertex2i(xmin,ymin); glTexCoord2f(0.0,th); glVertex2i(xmin,ymax); glTexCoord2f(tw,th); glVertex2i(xmax,ymax); glTexCoord2f(tw,0.0); glVertex2i(xmax,ymin); glEnd(); #endif glDisable(GL_TEXTURE_2D); } if(vis->isDoubleBuffer()) swapBuffers(); makeNonCurrent(); } return 1; } gogglesmm-0.12.7/src/GMColumnDialog.h0000644000175000001440000000426411525430601016051 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMCOLUMNDIALOG_H #define GMCOLUMNDIALOG_H class GMColumnDialog : public FXDialogBox { FXDECLARE(GMColumnDialog) protected: GMList * list; protected: GMColumnDialog(); private: GMColumnDialog(const GMColumnDialog&); GMColumnDialog& operator=(const GMColumnDialog&); public: enum { ID_MOVE_UP = FXDialogBox::ID_LAST, ID_MOVE_DOWN, ID_LIST, }; public: long onCmdMoveUp(FXObject*,FXSelector,void*); long onUpdMoveUp(FXObject*,FXSelector,void*); long onCmdMoveDown(FXObject*,FXSelector,void*); long onUpdMoveDown(FXObject*,FXSelector,void*); long onListLeftBtnPress(FXObject*,FXSelector,void*); public: /// Construct button with text and icon GMColumnDialog(FXWindow* p,GMColumnList & cols); void saveIndex(); }; #endif gogglesmm-0.12.7/src/md5.cpp0000644000175000001440000003022211011412341014250 0ustar sxjusers/* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ #include "md5.h" #include #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else # define BYTE_ORDER 0 #endif #define T_MASK ((md5_word_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ md5_word_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; #endif { #if BYTE_ORDER == 0 /* * Determine dynamically whether this is a big-endian or * little-endian machine, since we can use a more efficient * algorithm on the latter. */ static const int w = 1; if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ #endif #if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const md5_byte_t *)0) & 3)) { /* data are properly aligned */ X = (const md5_word_t *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } } #endif #if BYTE_ORDER == 0 else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const md5_byte_t *xp = data; int i; # if BYTE_ORDER == 0 X = xbuf; /* (dynamic only) */ # else # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #endif } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } void md5_init(md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { const md5_byte_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } gogglesmm-0.12.7/src/GMNotifyDaemon.h0000644000175000001440000000501711644107766016104 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMNOTIFY_H #define GMNOTIFY_H enum { IMAGE_WITHOUT_APPICON = 0x1, // Set if image and appicon may not be set at the same time ACTION_ITEMS = 0x2 }; class GMNotifyDaemon : public GMDBusProxy { FXDECLARE(GMNotifyDaemon) protected: FXuint flags; FXString appname; FXString appicon; FXString icondata; FXuint msgid; FXbool persistent; protected: GMNotifyDaemon(); private: GMNotifyDaemon(const GMNotifyDaemon&); GMNotifyDaemon& operator=(const GMNotifyDaemon&); public: enum { ID_NOTIFY_REPLY=1, ID_NOTIFY_CAPABILITIES, ID_NOTIFY_SERVER }; public: long onSignal(FXObject*,FXSelector,void*); long onMethod(FXObject*,FXSelector,void*); long onNotifyReply(FXObject*,FXSelector,void*); long onNotifyServer(FXObject*,FXSelector,void*); long onNotifyCapabilities(FXObject*,FXSelector,void*); public: GMNotifyDaemon(GMDBus*); void init(); void close(); void reset(); void notify(const FXchar * summary,const FXchar * body,FXint timeout,FXImage* img); public: void notify_track_change(const GMTrack & track,FXImage * cover); }; #endif gogglesmm-0.12.7/src/GMMediaPlayerService.h0000644000175000001440000000453011525430601017205 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2010-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMMPRISSERVICE_H #define GMMPRISSERVICE_H /* MPRIS v1 */ class GMMediaPlayerService : public FXObject { FXDECLARE(GMMediaPlayerService) protected: GMDBus * bus; FXbool published; protected: DBusObjectPathVTable root_vtable; DBusObjectPathVTable player_vtable; DBusObjectPathVTable tracklist_vtable; protected: static DBusHandlerResult root_filter(DBusConnection*,DBusMessage*,void *); static DBusHandlerResult player_filter(DBusConnection*,DBusMessage*,void *); static DBusHandlerResult tracklist_filter(DBusConnection*,DBusMessage*,void *); protected: GMMediaPlayerService(){} private: GMMediaPlayerService(const GMMediaPlayerService&); GMMediaPlayerService& operator=(const GMMediaPlayerService&); public: GMMediaPlayerService(GMDBus*); void notify_track_change(const GMTrack &); void notify_status_change(); void notify_caps_change(); virtual ~GMMediaPlayerService(); }; #endif gogglesmm-0.12.7/src/GMPlayer.cpp0000644000175000001440000007446711667530766015323 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include #include #include "gmdefs.h" #include "GMTrackDatabase.h" #include "GMList.h" #include "GMTrackList.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMPlayer.h" #include "GMWindow.h" #include "GMRemote.h" #include "GMTag.h" #define XINEVERSION ((XINE_SUB_VERSION)+(XINE_MINOR_VERSION*100)+(XINE_MAJOR_VERSION*10000)) GMEQBands::GMEQBands() { for (FXint i=0;i<10;i++) bands[i]=0; } GMEQBands::GMEQBands(FXdouble e0,FXdouble e1,FXdouble e2,FXdouble e3,FXdouble e4,FXdouble e5,FXdouble e6,FXdouble e7,FXdouble e8,FXdouble e9){ bands[0]=e0; bands[1]=e1; bands[2]=e2; bands[3]=e3; bands[4]=e4; bands[5]=e5; bands[6]=e6; bands[7]=e7; bands[8]=e8; bands[9]=e9; } GMEQBands::GMEQBands(const GMEQBands & v){ for (FXint i=0;i<10;i++) bands[i]=v.bands[i]; } void GMEQBands::unparse(FXString & preset) const { /// This is a really dirty and quick hack that is not garanteed to work. We need /// it for proper floating point to string conversion. /// xine will set the LC_NUMERIC locale in its threads, so we're not sure, /// when xine will change it. Luckily xine is already shutdown when we call this. setlocale(LC_NUMERIC,"C"); preset+=GMStringFormat("%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",bands[0],bands[1],bands[2],bands[3],bands[4],bands[5],bands[6],bands[7],bands[8],bands[9]); } void GMEQBands::parse(const FXString & preset) { /// This is a really dirty and quick hack that is not garanteed to work. We need /// it for proper floating point to string conversion. /// xine will set the LC_NUMERIC locale in its threads, so we're not sure, /// when xine will change it. Luckily xine is already shutdown when we call this. setlocale(LC_NUMERIC,"C"); if (!preset.empty()) { for (FXint i=0;i<10;i++) #if FOXVERSION < FXVERSION(1,7,0) bands[i]=FXDoubleVal(preset.section(',',i)); #else bands[i]=preset.section(',',i).toDouble(); #endif } } GMEqualizer::GMEqualizer() : preamp(0),enabled(false) { } GMEqualizer::GMEqualizer(const GMEQBands & v) : bands(v),preamp(0),enabled(true) { } void GMEqualizer::load(FXSettings & settings) { enabled=settings.readBoolEntry("audio-plugins","equalizer",enabled); FXString entry = settings.readStringEntry("audio-plugins","equalizer-bands",NULL); bands.parse(entry); } void GMEqualizer::save(FXSettings & settings) const { settings.writeBoolEntry("audio-plugins","equalizer",enabled); FXString entry; bands.unparse(entry); settings.writeStringEntry("audio-plugins","equalizer-bands",entry.text()); } const FXString xineconfigfile = FXSystem::getHomeDirectory() + PATHSEPSTRING + ".goggles" + PATHSEPSTRING + "xineconf"; FXDEFMAP(GMPlayer) GMPlayerMap[]={ FXMAPFUNCS(SEL_UPDATE,GMPlayer::ID_EQ_30HZ,GMPlayer::ID_EQ_16000HZ,GMPlayer::onUpdEqualizer), FXMAPFUNC(SEL_UPDATE,GMPlayer::ID_PREAMP,GMPlayer::onUpdPreamp), FXMAPFUNC(SEL_UPDATE,GMPlayer::ID_VOLUME,GMPlayer::onUpdVolume), FXMAPFUNC(SEL_UPDATE,GMPlayer::ID_MUTE,GMPlayer::onUpdMute), FXMAPFUNC(SEL_UPDATE,GMPlayer::ID_UNMUTE,GMPlayer::onUpdUnMute), FXMAPFUNC(SEL_UPDATE,GMPlayer::ID_TOGGLE_MUTE,GMPlayer::onUpdToggleMute), FXMAPFUNCS(SEL_COMMAND,GMPlayer::ID_EQ_30HZ,GMPlayer::ID_EQ_16000HZ,GMPlayer::onCmdEqualizer), FXMAPFUNCS(SEL_CHANGED,GMPlayer::ID_EQ_30HZ,GMPlayer::ID_EQ_16000HZ,GMPlayer::onCmdEqualizer), FXMAPFUNC(SEL_COMMAND,GMPlayer::ID_PREAMP,GMPlayer::onCmdPreamp), FXMAPFUNC(SEL_CHANGED,GMPlayer::ID_PREAMP,GMPlayer::onCmdPreamp), FXMAPFUNC(SEL_COMMAND,GMPlayer::ID_VOLUME,GMPlayer::onCmdVolume), FXMAPFUNC(SEL_CHANGED,GMPlayer::ID_VOLUME,GMPlayer::onCmdVolume), FXMAPFUNC(SEL_COMMAND,GMPlayer::ID_MUTE,GMPlayer::onCmdMute), FXMAPFUNC(SEL_COMMAND,GMPlayer::ID_UNMUTE,GMPlayer::onCmdUnMute), FXMAPFUNC(SEL_COMMAND,GMPlayer::ID_TOGGLE_MUTE,GMPlayer::onCmdToggleMute), }; FXIMPLEMENT(GMPlayer,FXObject,GMPlayerMap,ARRAYNUMBER(GMPlayerMap)) GMPlayer::GMPlayer(){ } GMPlayer::GMPlayer(int argc,char** argv) : FXObject(), xine(NULL),ao(NULL),so(NULL),queue(NULL), post_volume_normalize(NULL) { position=0; ctime=0; ttime=0; hours=0; minutes=0; seconds=0; volume=0; repeat_a=-1; repeat_b=-1; ignore_uimsg=false; debug=false; for (FXint i=1;ireg()); } GMPlayer::~GMPlayer(){ close(); } FXbool GMPlayer::opened() const { if (xine && so) return true; else return false; } FXbool GMPlayer::init() { if (xine == NULL) { /// Create Xine xine = xine_new(); /// load xine config file and init xine xine_config_load(xine,xineconfigfile.text()); /// Init the Engine xine_init(xine); /// Enable Debug Output if (debug) xine_engine_set_param(xine,XINE_ENGINE_PARAM_VERBOSITY,XINE_VERBOSITY_DEBUG); } /// Open Audio Driver if (ao == NULL) { FXString audio_driver = FXApp::instance()->reg().readStringEntry("xine","driver",NULL); if (!audio_driver.empty() && audio_driver!="auto") { ao = xine_open_audio_driver(xine,audio_driver.text(),NULL); if (ao) FXApp::instance()->reg().writeStringEntry("xine","driver",audio_driver.text()); } if (ao == NULL) { const char *const * plugins = xine_list_audio_output_plugins(xine); for (FXint i=0;plugins[i]!=NULL;i++){ if (compare(plugins[i],"none") && compare(plugins[i],"file") ){ ao = xine_open_audio_driver(xine,plugins[i],NULL); if (ao) { FXApp::instance()->reg().writeStringEntry("xine","driver",plugins[i]); break; } } } } if (ao == NULL ) { msg=fxtr("Unable to initialize audio driver."); return false; } } FXASSERT(so==NULL); /// Open Default Stream so = xine_stream_new(xine,ao,NULL); if (so == NULL) { msg="Unable to create a new stream for playback."; xine_close_audio_driver(xine,ao); return false; } if (FXApp::instance()->reg().readBoolEntry("audio-plugins","volume-normalization",false) && hasVolumeNormalization()) { setVolumeNormalization(true); } /// Create Event Queue for Stream queue = xine_event_new_queue(so); /// Init Volume volume = xine_get_param(so,XINE_PARAM_AUDIO_VOLUME); /// Faster Seeking //xine_set_param(so,XINE_PARAM_METRONOM_PREBUFFER,6000); /// Ignore Video xine_set_param(so,XINE_PARAM_IGNORE_VIDEO,1); /// Ignore SPU xine_set_param(so,XINE_PARAM_IGNORE_SPU,1); /// Init the Equalizer setEqualizer(equalizer); /// Debug Output if (debug) xine_set_param(so,XINE_PARAM_VERBOSITY,XINE_VERBOSITY_DEBUG); return true; } void GMPlayer::getCurrentDriver(FXString & driver) { driver=FXApp::instance()->reg().readStringEntry("xine","driver","auto"); } void GMPlayer::getAvailableDrivers(FXString & drivers) { const char *const * plugins = xine_list_audio_output_plugins(xine); for (FXint i=0;plugins[i]!=NULL;i++){ if (compare(plugins[i],"none") && compare(plugins[i],"file") ){ if (!drivers.empty()) drivers+="\n"; drivers+=plugins[i]; } } /* xine_cfg_entry_t entry; for (xine_config_get_first_entry(xine,&entry);xine_config_get_next_entry(xine,&entry);){ if (entry.exp_level==0) fxmessage("key %d: %s\n",entry.exp_level,entry.key); } */ } void GMPlayer::setupGapless() { if (so) { #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if (xine_check_version(1,1,1) && GMPlayerManager::instance()->getPreferences().play_gapless && gm_is_local_file(mrl)) { xine_set_param(so,XINE_PARAM_EARLY_FINISHED_EVENT,1); } else { xine_set_param(so,XINE_PARAM_EARLY_FINISHED_EVENT,0); } #endif } } FXbool GMPlayer::hasGapless() const{ #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if (xine_check_version(1,1,1)) return true; #endif return false; } FXbool GMPlayer::hasVolumeNormalization() const { if (post_volume_normalize) return true; const char * const * filters = xine_list_post_plugins_typed(xine,XINE_POST_TYPE_AUDIO_FILTER); for (FXint i=0;filters[i];i++){ if (comparecase(filters[i],"volnorm")==0) return true; } return false; } void GMPlayer::setVolumeNormalization(FXbool enable){ if (enable) { if (post_volume_normalize) return; xine_audio_port_t * targets[2]={ao,NULL}; post_volume_normalize = xine_post_init(xine,"volnorm",1,targets,NULL); if (post_volume_normalize) { xine_post_out_t * source = xine_get_audio_source(so); xine_post_wire_audio_port(source,post_volume_normalize->audio_input[0]); FXApp::instance()->reg().writeBoolEntry("audio-plugins","volume-normalization",true); } } else { if (!post_volume_normalize) return; xine_post_out_t * source = xine_get_audio_source(so); xine_post_wire_audio_port(source,ao); xine_post_dispose(xine,post_volume_normalize); post_volume_normalize = NULL; FXApp::instance()->reg().writeBoolEntry("audio-plugins","volume-normalization",false); } } void GMPlayer::getErrorMessage(FXString & errormsg) { errormsg=msg; } void GMPlayer::check_xine_error() { FXint error = xine_get_error(so); switch(error) { case XINE_ERROR_NO_INPUT_PLUGIN: msg="No input plugin found to play:\n" + mrl; break; case XINE_ERROR_NO_DEMUX_PLUGIN: msg="No demux plugin found to play:\n" + mrl; break; case XINE_ERROR_DEMUX_FAILED: msg="Unable to play:\n" + mrl; break; case XINE_ERROR_INPUT_FAILED: msg="Unable to open:\n" + mrl; break; case XINE_ERROR_MALFORMED_MRL: msg="Resource does not exist:\n" + mrl; break; case XINE_ERROR_NONE: msg="Nothing to report\n"; default: msg="Unknown error while trying to play:\n" + mrl; break; } ignore_uimsg=true; } FXbool GMPlayer::checkInitialized() { if (!so && !init()) return false; return true; } FXbool GMPlayer::initialize() { if (!so && !init()) return false; return true; } FXbool GMPlayer::open(const FXString & mrl_in){ if (!so && !init()) return false; mrl=mrl_in; /// Make sure we encode #. if (mrl[0]=='/') { mrl.substitute("#","%23"); mrl.prepend("file:"); } /// Open Mrl if (xine_open(so,mrl.text())==0){ /// Disable Gapless Playback #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)){ xine_set_param(so,XINE_PARAM_GAPLESS_SWITCH,0); } #endif check_xine_error(); return false; } setupGapless(); progress=100; return true; } void GMPlayer::close_device(){ #ifdef XINE_PARAM_AUDIO_CLOSE_DEVICE if (xine && so) { xine_set_param(so,XINE_PARAM_AUDIO_CLOSE_DEVICE,1); } #endif } FXbool GMPlayer::changeDriver(const FXString & driver) { if (post_volume_normalize) { xine_post_out_t * source = xine_get_audio_source(so); xine_post_wire_audio_port(source,ao); xine_post_dispose(xine,post_volume_normalize); post_volume_normalize=NULL; } if (queue) { xine_event_dispose_queue(queue); queue=NULL; } if (so) { stop(); xine_dispose(so); so=NULL; } if (ao) { xine_close_audio_driver(xine,ao); ao=NULL; } /// Set the new driver FXApp::instance()->reg().writeStringEntry("xine","driver",driver.text()); /// Initialize the system return initialize(); } void GMPlayer::close(){ #if XINEVERSION >= 10001 if (xine && xine_check_version(1,0,1)) { xine_plugins_garbage_collector(xine); } #endif if (xine) { xine_config_save(xine,xineconfigfile.text()); } if (post_volume_normalize) { xine_post_out_t * source = xine_get_audio_source(so); xine_post_wire_audio_port(source,ao); xine_post_dispose(xine,post_volume_normalize); post_volume_normalize=NULL; } if (queue) { xine_event_dispose_queue(queue); queue=NULL; } if (so) { stop(); xine_dispose(so); so=NULL; } if (ao) { xine_close_audio_driver(xine,ao); ao=NULL; } if (xine){ xine_exit(xine); xine=NULL; } equalizer.save(FXApp::instance()->reg()); } FXbool GMPlayer::seekable() const { if (xine && so && (xine_get_status(so)==XINE_STATUS_PLAY) && xine_get_stream_info(so,XINE_STREAM_INFO_SEEKABLE)) return true; else return false; } void GMPlayer::setRepeatAB() { if ((repeat_a>=0 && repeat_b>=0) || !seekable()) { repeat_a=-1; repeat_b=-1; } else if (repeat_a==-1 || position==repeat_a) repeat_a=position; else if (repeat_a=0 && repeat_b>=0){ if (pos>repeat_b || pos=100) return true; else return false; } FXbool GMPlayer::playing() const { return (so && xine_get_status(so)==XINE_STATUS_PLAY); } void GMPlayer::setSpeed(FXint speed){ if (so) xine_set_param(so,XINE_PARAM_SPEED,speed); } FXint GMPlayer::getSpeed() const { return so ? xine_get_param(so,XINE_PARAM_SPEED) : 0; } void GMPlayer::incSpeed(){ FXint oldspeed=getSpeed(); if (oldspeed>=XINE_SPEED_FAST_4) return; setSpeed(oldspeed*2); } void GMPlayer::decSpeed(){ FXint oldspeed=getSpeed(); if (oldspeed<=XINE_SPEED_SLOW_4) return; setSpeed(oldspeed/2); } void GMPlayer::handle_async_events(){ if (queue == NULL) return; xine_event_t * event =NULL; xine_ui_message_data_t * data =NULL; FXString uimsg; static FXString newmrl; /// First Get All Pending Events while((event = xine_event_get(queue))!=NULL){ switch(event->type){ case XINE_EVENT_AUDIO_LEVEL : volume=static_cast(event->data)->left; GMPlayerManager::instance()->getMainWindow()->update_volume_display(volume); break; case XINE_EVENT_UI_CHANNELS_CHANGED : break; case XINE_EVENT_UI_SET_TITLE : //fxmessage("Title Changed\n"); FXApp::instance()->addTimeout(GMPlayerManager::instance(),GMPlayerManager::ID_UPDATE_TRACK_DISPLAY,TIME_SEC(5)); //GMPlayerManager::instance()->update_track_display(); break; case XINE_EVENT_FRAME_FORMAT_CHANGE : break; case XINE_EVENT_QUIT : break; case XINE_EVENT_PROGRESS : //fxmessage("progress callback %d\n",xine_get_status(so)); if (xine_get_status(so)==XINE_STATUS_PLAY) { progress=static_cast(event->data)->percent; if (progress>=100){ //fxmessage("Update track display %d\n",progress); //GMPlayerManager::instance()->update_track_display(); /// let's wait a little, to give xine some time to get the latest track information... FXApp::instance()->addTimeout(GMPlayerManager::instance(),GMPlayerManager::ID_UPDATE_TRACK_DISPLAY,TIME_SEC(5)); } else { FXString status; status.format("%s - %d%%\n",static_cast(event->data)->description,static_cast(event->data)->percent); GMPlayerManager::instance()->setStatus(status); } } break; #ifdef XINE_EVENT_MRL_REFERENCE_EXT case XINE_EVENT_MRL_REFERENCE_EXT : newmrl=static_cast(event->data)->mrl; // fxmessage("Received MRL reference: %s\n",static_cast(event->data)->mrl); // GMPlayerManager::instance()->play(static_cast(event->data)->mrl); break; #else case XINE_EVENT_MRL_REFERENCE : newmrl=static_cast(event->data)->mrl; // fxmessage("Received MRL reference: %s\n",static_cast(event->data)->mrl); // GMPlayerManager::instance()->play(static_cast(event->data)->mrl); break; #endif case XINE_EVENT_UI_NUM_BUTTONS : break; case XINE_EVENT_SPU_BUTTON : break; case XINE_EVENT_DROPPED_FRAMES : break; case XINE_EVENT_UI_PLAYBACK_FINISHED: if (!newmrl.empty()) { if (xine_get_status(so)==XINE_STATUS_STOP) { GMPlayerManager::instance()->play(newmrl); } newmrl=FXString::null; } else { #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1) && GMPlayerManager::instance()->getPreferences().play_gapless && !GMPlayerManager::instance()->playlist_empty() && gm_is_local_file(mrl) ){ xine_set_param(so,XINE_PARAM_GAPLESS_SWITCH,1); } #endif /// For very short tracks we need to get the latest time. xine_get_pos_length(so,&position,&ctime,&ttime); GMPlayerManager::instance()->notify_playback_finished(); /* Return here so we don't want to update the time. Xine will report 0, if we call it too soon which we don't want. */ xine_event_free(event); return; } break; case XINE_EVENT_UI_MESSAGE : //fxmessage("UI message\n"); if (!ignore_uimsg) { data = (xine_ui_message_data_t*)event->data; switch(data->type) { case XINE_MSG_NO_ERROR : break; case XINE_MSG_ENCRYPTED_SOURCE : break; case XINE_MSG_UNKNOWN_HOST : uimsg = fxtr("Unknown host."); break; case XINE_MSG_UNKNOWN_DEVICE : uimsg = fxtr("Unknown device"); break; case XINE_MSG_NETWORK_UNREACHABLE : uimsg = fxtr("Network not reachable."); break; case XINE_MSG_AUDIO_OUT_UNAVAILABLE : uimsg = fxtr("Audio output unavailable."); break; case XINE_MSG_CONNECTION_REFUSED : uimsg = fxtr("Connection Refused."); break; case XINE_MSG_FILE_NOT_FOUND : uimsg = fxtr("File not found."); break; case XINE_MSG_PERMISSION_ERROR : uimsg = fxtr("Resource not accessible. Check permissions"); break; case XINE_MSG_READ_ERROR : uimsg = fxtr("Read Error"); break; case XINE_MSG_LIBRARY_LOAD_ERROR : uimsg = fxtr("Error while loading library/plugin"); break; case XINE_MSG_GENERAL_WARNING : uimsg = fxtr("Warning"); break; case XINE_MSG_SECURITY : uimsg = fxtr("Security Warning"); break; default : uimsg = fxtr("Unknown Error"); break; } } ignore_uimsg=false; break; default: /*unhandled event*/ break; } xine_event_free(event); event=NULL; } if (xine_get_status(so)==XINE_STATUS_PLAY) { if (xine_get_param(so,XINE_PARAM_SPEED)!=XINE_SPEED_PAUSE) { if (xine_get_pos_length(so,&position,&ctime,&ttime)){ FXint time=ctime; hours = (FXint) floor((double)time/3600000.0); time -= (FXint) (3600000.0*hours); minutes = (FXint) floor((double)time/60000.0); time -= (FXint) (60000.0*minutes); seconds = (FXint) floor((double)time/1000.0); } } if (repeat_b>=0 && repeat_a>=0 && repeat_b>repeat_a && (position>repeat_b || positionstop(); GMPlayerManager::instance()->show_message(fxtr("Error"),uimsg.text()); } } /// Audio Controls FXint GMPlayer::remaining() const { FXint r = ttime-ctime; return (FXint) floor((double)r/1000.0); } FXint GMPlayer::getVolume() const { return volume; } void GMPlayer::setVolume(FXint level){ if (so == NULL) return; volume=level; //xine_set_param( so, XINE_PARAM_AUDIO_AMP_LEVEL,(FXuint)(level*preamp)); xine_set_param(so,XINE_PARAM_AUDIO_VOLUME,level); if (level==0 && !pausing() ) pause(); if (level>0 && pausing() ) unpause(); } FXbool GMPlayer::isMute() const { return so ? xine_get_param(so,XINE_PARAM_AUDIO_MUTE) : true; } void GMPlayer::mute(){ if (so) xine_set_param(so,XINE_PARAM_AUDIO_MUTE,1); } void GMPlayer::unmute(){ if (so) xine_set_param(so,XINE_PARAM_AUDIO_MUTE,0); } void GMPlayer::disableEqualizer() { equalizer.enabled=false; if (so) { for (FXint i=0;i<10;i++){ xine_set_param(so,XINE_PARAM_EQ_30HZ+i,0); } } } void GMPlayer::getEqualizer(GMEqualizer & eq){ eq=equalizer; } void GMPlayer::setEqualizer(const GMEqualizer & eq) { FXint oldamp=equalizer.preamp; equalizer=eq; equalizer.preamp=oldamp; if (so) { if (equalizer.enabled) { for (FXint i=0;i<10;i++){ xine_set_param(so,XINE_PARAM_EQ_30HZ+i,equalizer.to_xine(i)); } } else { for (FXint i=0;i<10;i++){ xine_set_param(so,XINE_PARAM_EQ_30HZ+i,0); } } } } void GMPlayer::setReplayGain(FXdouble gain,FXdouble peak){ if (replaygain.gain!=gain || replaygain.peak!=peak) { replaygain.gain=gain; replaygain.peak=peak; #ifdef DEBUG fxmessage("replay gain: %g %g\n",gain,peak); #endif set_preamp(); } } void GMPlayer::set_preamp() { FXdouble scale; FXdouble gain_scale; if (!isnan(replaygain.gain)){ gain_scale=pow(10.0,replaygain.gain/20.0); if (equalizer.enabled) { /// with preamp scale=(equalizer.preamp_scale()*gain_scale); /// avoid clipping if (!isnan(replaygain.peak) && replaygain.peak!=0.0) { if ((scale*replaygain.peak)>1.0){ if ((gain_scale*replaygain.peak)>1.0) scale=1.0 / replaygain.peak; else scale=gain_scale; } } } else { /// no preamp scale = gain_scale; /// avoid clipping if (!isnan(replaygain.peak) && replaygain.peak!=0.0 && (gain_scale*replaygain.peak)>1.0) scale=1.0 / replaygain.peak; } xine_set_param(so,XINE_PARAM_AUDIO_AMP_LEVEL,(FXint)(100.0*scale)); } else if (equalizer.enabled) { /// preamp only //fxmessage("preamp: %d\n",equalizer.to_xine_preamp()); xine_set_param(so,XINE_PARAM_AUDIO_AMP_LEVEL,equalizer.to_xine_preamp()); } else { /// disabled xine_set_param(so,XINE_PARAM_AUDIO_AMP_LEVEL,100); } } long GMPlayer::onCmdPreamp(FXObject*sender,FXSelector,void*){ if (so) { FXdouble value; sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_GETREALVALUE),(void*)&value); equalizer.preamp=value;//FXCLAMP(-100,value,100); set_preamp(); } return 1; } long GMPlayer::onUpdPreamp(FXObject*sender,FXSelector,void*){ if (equalizer.enabled) { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETREALVALUE),(void*)&equalizer.preamp); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETVALUE),NULL); /// for textfield NULL is string, for slider, NULL will be 0 } return 1; } long GMPlayer::onUpdEqualizer(FXObject*sender,FXSelector sel,void*){ if (equalizer.enabled) { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETREALVALUE),(void*)&equalizer.bands[FXSELID(sel)-ID_EQ_30HZ]); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETVALUE),NULL); /// for textfield NULL is string, for slider, NULL will be 0 } return 1; } long GMPlayer::onCmdEqualizer(FXObject*sender,FXSelector sel,void*){ /// don't bother reading EQ values from xine. /// due to rounding errors, the correct value won't be returned. FXdouble value; FXint which=FXSELID(sel)-ID_EQ_30HZ; sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_GETREALVALUE),(void*)&value); equalizer.bands[which]=FXCLAMP(-6,value,6); if (so) { xine_set_param(so,XINE_PARAM_EQ_30HZ+which,equalizer.to_xine(which)); } return 1; } const char * GMPlayer::getVersion() const{ return xine_get_version_string(); } /// Message Handlers long GMPlayer::onCmdVolume(FXObject*,FXSelector,void*ptr){ FXint level = (FXint)(FXival)ptr; setVolume(level); return 1; } long GMPlayer::onUpdVolume(FXObject*sender,FXSelector,void*){ FXWindow * window = (FXWindow*)sender; if (window->getShell()->shown()){ sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SETINTVALUE),&volume); return 1; } return 0; } long GMPlayer::onCmdMute(FXObject*,FXSelector,void*){ mute(); return 1; } long GMPlayer::onUpdMute(FXObject*sender,FXSelector,void*){ if (isMute()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); return 1; } long GMPlayer::onCmdUnMute(FXObject*,FXSelector,void*){ unmute(); return 1; } long GMPlayer::onUpdUnMute(FXObject*sender,FXSelector,void*){ if (isMute()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMPlayer::onCmdToggleMute(FXObject*,FXSelector,void*){ if (isMute()) unmute(); else mute(); return 1; } long GMPlayer::onUpdToggleMute(FXObject*sender,FXSelector,void*){ if (isMute()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); return 1; } void GMPlayer::getTrackInformation(GMTrack & info){ info.clear(); info.mrl = mrl; info.artist = xine_get_meta_info(so,XINE_META_INFO_ARTIST); info.album = xine_get_meta_info(so,XINE_META_INFO_ALBUM); info.title = xine_get_meta_info(so,XINE_META_INFO_TITLE); info.genre = xine_get_meta_info(so,XINE_META_INFO_GENRE); #if FOXVERSION >= FXVERSION(1,7,12) info.year = FXString(xine_get_meta_info(so,XINE_META_INFO_YEAR)).toInt(); info.no = FXString(xine_get_meta_info(so,XINE_META_INFO_TRACK_NUMBER)).toInt(); #else info.year = FXIntVal(xine_get_meta_info(so,XINE_META_INFO_YEAR)); info.no = FXIntVal(xine_get_meta_info(so,XINE_META_INFO_TRACK_NUMBER)); #endif info.time = 0; if (xine_get_pos_length(so,NULL,NULL,&info.time)){ info.time/=1000; } info.bitrate=xine_get_stream_info(so,XINE_STREAM_INFO_BITRATE); if (info.bitrate==0) info.bitrate=xine_get_stream_info(so,XINE_STREAM_INFO_AUDIO_BITRATE); //fxmessage("Playing %s - %s\n",info.artist.text(),info.title.text()); } FXbool GMPlayer::setStringValue(const FXString & entry,const FXString & value){ xine_cfg_entry_t config; if (xine_config_lookup_entry(xine,entry.text(),&config)) { config.str_value = (FXchar*)value.text(); xine_config_update_entry (xine,&config); return true; } return false; } #if 0 void GMPlayer::list_cda_tracks(GMTrackDatabase * db,const FXString & device) { GMTrack track; FXchar ** tracks; FXint num_tracks; FXint id; if (!setStringValue("media.audio_cd.device",device)) return; tracks = xine_get_autoplay_mrls(xine,"CD",&num_tracks); if (num_tracks) { for (int i=0;igetPreferences().import_default_user_title; if (track.artist.empty()) track.artist = GMPlayerManager::instance()->getPreferences().import_default_user_artist; if (track.album.empty()) track.album = GMPlayerManager::instance()->getPreferences().import_default_user_album; if (track.genre.empty()) track.genre = GMPlayerManager::instance()->getPreferences().import_default_user_genre; if (track.no==0) track.no=i+1; db->insertTrack(track,id); } } } } #endif gogglesmm-0.12.7/src/GMPreferences.cpp0000644000175000001440000004151411644100423016265 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMFilename.h" const char section_window[] = "window"; const char section_import[] = "import"; const char section_export[] = "export"; const char section_player[] = "player"; const char section_colors[] = "colors"; const char section_dbus[] = "dbus"; const char section_app[] = "application"; const char section_sync[] = "sync"; const char key_import_default_field[]="default-user-title"; const char key_import_track_from_filelist[]="track-from-filelist"; const char key_import_replace_underscores[]="replace-underscores"; const char key_import_parse_filename_only[]="parse-filename-only"; const char key_import_filename_template[]="filename-template"; const char key_import_parse_method[]="parse-method"; const char key_import_exclude_folder[]="exclude-folder"; const char key_import_exclude_file[]="exclude-file"; const char key_export_format_template[]="format-template"; const char key_export_character_filter[]="character-filter"; const char key_export_encoding[]="encoding"; const char key_export_lowercase[]="lowercase"; const char key_export_lowercase_extension[]="lowercase-extension"; const char key_export_underscore[]="underscore"; const char key_gui_format_title[]="title-format"; const char key_gui_show_status_bar[]="show-statusbar"; const char key_gui_hide_player_when_close[]="hide-player-when-close"; const char key_gui_toolbar_bigicons[]="toolbar-bigicons"; const char key_gui_toolbar_docktop[]="toolbar-docktop"; const char key_gui_toolbar_showlabels[]="toolbar-labels"; const char key_gui_show_browser_icons[]="browser-icons"; const char key_gui_keywords[]="sort-keywords"; const char key_gui_show_playing_albumcover[]="show-playing-albumcover"; const char key_gui_show_albumcovers[]="show-albumcovers"; const char key_gui_tray_icon[]="tray-icon"; const char key_gui_show_playing_titlebar[]="show-playing-titlebar"; const char key_gui_coverdisplay_size[]="cover-display-size"; const char key_gui_show_opengl_coverview[]="show-opengl-coverview"; const char key_gui_row_color[]="row-color"; const char key_gui_play_color[]="play-color"; const char key_gui_playtext_color[]="playtext-color"; const char key_gui_tray_color[]="tray-back-color"; const char key_play_repeat[]="repeat-mode"; const char key_play_replaygain[]="replay-gain"; const char key_play_close_stream[]="close-audio-stream"; const char key_play_pause_close_device[]="pause-close-device"; const char key_play_gapless[]="gapless-playback"; const char key_play_shuffle[]="shuffle"; const char key_play_open_device_on_startup[]="open_audio_device_on_startup"; const char key_dbus_notify_daemon[]="notification-daemon"; const char key_sync_import_new[]="import-new"; const char key_sync_remove_missing[]="remove-missing"; const char key_sync_remove_all[]="remove-all"; const char key_sync_update[]="update"; const char key_sync_update_always[]="update-always"; GMImportOptions::GMImportOptions() : default_field("Untitled"), filename_template("%P/%A/%N %T"), track_from_filelist(false), replace_underscores(true), parse_method(PARSE_BOTH){ } void GMImportOptions::save(FXSettings & reg) const { reg.writeBoolEntry(section_import,key_import_track_from_filelist,track_from_filelist); reg.writeBoolEntry(section_import,key_import_replace_underscores,replace_underscores); reg.writeStringEntry(section_import,key_import_default_field,default_field.text()); reg.writeStringEntry(section_import,key_import_filename_template,filename_template.text()); reg.writeStringEntry(section_import,key_import_exclude_folder,exclude_folder.text()); reg.writeStringEntry(section_import,key_import_exclude_file,exclude_file.text()); #if FOXVERSION < FXVERSION(1,7,0) reg.writeUnsignedEntry(section_import,key_import_parse_method,parse_method); #else reg.writeUIntEntry(section_import,key_import_parse_method,parse_method); #endif } void GMImportOptions::load(FXSettings & reg) { track_from_filelist = reg.readBoolEntry(section_import,key_import_track_from_filelist,track_from_filelist); replace_underscores = reg.readBoolEntry(section_import,key_import_replace_underscores,replace_underscores); default_field = reg.readStringEntry(section_import,key_import_default_field,default_field.text()); filename_template = reg.readStringEntry(section_import,key_import_filename_template,filename_template.text()); exclude_folder = reg.readStringEntry(section_import,key_import_exclude_folder,exclude_folder.text()); exclude_file = reg.readStringEntry(section_import,key_import_exclude_file,exclude_file.text()); #if FOXVERSION < FXVERSION(1,7,0) parse_method = FXMIN(reg.readUnsignedEntry(section_import,key_import_parse_method,parse_method),(FXuint)PARSE_BOTH); #else parse_method = FXMIN(reg.readUIntEntry(section_import,key_import_parse_method,parse_method),(FXuint)PARSE_BOTH); #endif } GMSyncOptions::GMSyncOptions() : import_new(true), remove_missing(true), remove_all(false), update(false), update_always(false) { } void GMSyncOptions::save(FXSettings & reg) const { reg.writeBoolEntry(section_sync,key_sync_import_new,import_new); reg.writeBoolEntry(section_sync,key_sync_remove_missing,remove_missing); reg.writeBoolEntry(section_sync,key_sync_remove_all,remove_all); reg.writeBoolEntry(section_sync,key_sync_update,update); reg.writeBoolEntry(section_sync,key_sync_update_always,update_always); } void GMSyncOptions::load(FXSettings & reg) { import_new = reg.readBoolEntry(section_sync,key_sync_import_new,import_new); remove_missing = reg.readBoolEntry(section_sync,key_sync_remove_missing,remove_missing); remove_all = reg.readBoolEntry(section_sync,key_sync_remove_all,remove_all); update = reg.readBoolEntry(section_sync,key_sync_update,update); update_always = reg.readBoolEntry(section_sync,key_sync_update_always,update_always); } GMPreferences::GMPreferences() : export_format_template("%N %T"), export_character_filter("\'\\#~!\"$&();<>|`^*?[]/.:"), gui_format_title("%N - %T - %P"), gui_show_status_bar(true), gui_hide_player_when_close(false), gui_toolbar_bigicons(true), gui_toolbar_docktop(true), gui_toolbar_showlabels(true), gui_show_browser_icons(true), gui_show_playing_albumcover(false), gui_show_albumcovers(false), gui_tray_icon(false), gui_tray_icon_disabled(false), gui_show_playing_titlebar(false), gui_show_opengl_coverview(true), gui_coverdisplay_size(256), play_replaygain(REPLAYGAIN_OFF), play_repeat(REPEAT_ALL), play_close_stream(false), play_pause_close_device(false), play_gapless(true), play_shuffle(false), play_open_device_on_startup(false), export_encoding(GMFilename::ENCODING_ASCII), export_lowercase(false), export_lowercase_extension(true), export_underscore(false), dbus_notify_daemon(false) { resetColors(); } void GMPreferences::save(FXSettings & reg) const { FXString keywords; getKeyWords(keywords); /// Write out version information reg.writeIntEntry(section_app,"major-version",APPLICATION_MAJOR); reg.writeIntEntry(section_app,"minor-version",APPLICATION_MINOR); reg.writeIntEntry(section_app,"level-version",APPLICATION_LEVEL); import.save(reg); sync.save(reg); /// Export reg.writeBoolEntry(section_export,key_export_lowercase,export_lowercase); reg.writeBoolEntry(section_export,key_export_lowercase_extension,export_lowercase_extension); reg.writeBoolEntry(section_export,key_export_underscore,export_underscore); reg.writeStringEntry(section_export,key_export_format_template,export_format_template.text()); reg.writeStringEntry(section_export,key_export_character_filter,export_character_filter.text()); #if FOXVERSION < FXVERSION(1,7,0) reg.writeUnsignedEntry(section_export,key_export_encoding,export_encoding); #else reg.writeUIntEntry(section_export,key_export_encoding,export_encoding); #endif /// Colors reg.writeColorEntry(section_colors,key_gui_row_color,gui_row_color); reg.writeColorEntry(section_colors,key_gui_play_color,gui_play_color); reg.writeColorEntry(section_colors,key_gui_playtext_color,gui_playtext_color); reg.writeColorEntry(section_colors,key_gui_tray_color,gui_tray_color); /// Window reg.writeBoolEntry(section_window,key_gui_hide_player_when_close,gui_hide_player_when_close); reg.writeBoolEntry(section_window,key_gui_show_status_bar,gui_show_status_bar); reg.writeBoolEntry(section_window,key_gui_toolbar_bigicons,gui_toolbar_bigicons); reg.writeBoolEntry(section_window,key_gui_toolbar_docktop,gui_toolbar_docktop); reg.writeBoolEntry(section_window,key_gui_toolbar_showlabels,gui_toolbar_showlabels); reg.writeBoolEntry(section_window,key_gui_show_browser_icons,gui_show_browser_icons); reg.writeStringEntry(section_window,key_gui_keywords,keywords.text()); reg.writeBoolEntry(section_window,key_gui_show_playing_albumcover,gui_show_playing_albumcover); reg.writeBoolEntry(section_window,key_gui_show_albumcovers,gui_show_albumcovers); reg.writeBoolEntry(section_window,key_gui_tray_icon,gui_tray_icon); reg.writeBoolEntry(section_window,key_gui_show_playing_titlebar,gui_show_playing_titlebar); reg.writeBoolEntry(section_window,key_gui_show_opengl_coverview,gui_show_opengl_coverview); reg.writeIntEntry(section_window,key_gui_coverdisplay_size,gui_coverdisplay_size); reg.writeStringEntry(section_window,key_gui_format_title,gui_format_title.text()); /// Player reg.writeIntEntry(section_player,key_play_repeat,play_repeat); reg.writeIntEntry(section_player,key_play_replaygain,play_replaygain); reg.writeBoolEntry(section_player,key_play_close_stream,play_close_stream); reg.writeBoolEntry(section_player,key_play_pause_close_device,play_pause_close_device); reg.writeBoolEntry(section_player,key_play_gapless,play_gapless); reg.writeBoolEntry(section_player,key_play_shuffle,play_shuffle); reg.writeBoolEntry(section_player,key_play_open_device_on_startup,play_open_device_on_startup); /// Dbus reg.writeBoolEntry(section_dbus,key_dbus_notify_daemon,dbus_notify_daemon); } void GMPreferences::load(FXSettings & reg) { FXString keywords="a;an;the"; /// Remove Keys that interfere with new ones.. if (reg.readIntEntry(section_app,"major-version",0)==0 && reg.readIntEntry(section_app,"minor-version",8)<9) { FXint s; FXStringDict *dict; for (s = reg.first(); s < reg.size(); s = reg.next(s)){ dict = reg.data(s); dict->remove("browse-showcolumn-no"); dict->remove("list-showcolumn-no"); } } /// Write out version information reg.writeIntEntry(section_app,"major-version",APPLICATION_MAJOR); reg.writeIntEntry(section_app,"minor-version",APPLICATION_MINOR); reg.writeIntEntry(section_app,"level-version",APPLICATION_LEVEL); import.load(reg); sync.load(reg); /// Export export_lowercase = reg.readBoolEntry(section_export,key_export_lowercase,export_lowercase); export_lowercase_extension = reg.readBoolEntry(section_export,key_export_lowercase_extension,export_lowercase_extension); export_underscore = reg.readBoolEntry(section_export,key_export_underscore,export_underscore); export_format_template = reg.readStringEntry(section_export,key_export_format_template,export_format_template.text()); export_character_filter = reg.readStringEntry(section_export,key_export_character_filter,export_character_filter.text()); #if FOXVERSION < FXVERSION(1,7,0) export_encoding = FXMIN(GMFilename::ENCODING_LAST-1,reg.readUnsignedEntry(section_export,key_export_encoding,export_encoding)); #else export_encoding = FXMIN(GMFilename::ENCODING_LAST-1,reg.readUIntEntry(section_export,key_export_encoding,export_encoding)); #endif /// Colors gui_row_color = reg.readColorEntry(section_colors,key_gui_row_color,gui_row_color); gui_play_color = reg.readColorEntry(section_colors,key_gui_play_color,gui_play_color); gui_playtext_color = reg.readColorEntry(section_colors,key_gui_playtext_color,gui_playtext_color); gui_tray_color = reg.readColorEntry(section_colors,key_gui_tray_color,FXApp::instance()->getBaseColor()); /// Window gui_hide_player_when_close = reg.readBoolEntry(section_window,key_gui_hide_player_when_close,gui_hide_player_when_close); gui_show_status_bar = reg.readBoolEntry(section_window,key_gui_show_status_bar,gui_show_status_bar); gui_toolbar_bigicons = reg.readBoolEntry(section_window,key_gui_toolbar_bigicons,gui_toolbar_bigicons); gui_toolbar_docktop = reg.readBoolEntry(section_window,key_gui_toolbar_docktop,gui_toolbar_docktop); gui_toolbar_showlabels = reg.readBoolEntry(section_window,key_gui_toolbar_showlabels,gui_toolbar_showlabels); gui_show_browser_icons = reg.readBoolEntry(section_window,key_gui_show_browser_icons,gui_show_browser_icons); keywords = reg.readStringEntry(section_window,key_gui_keywords,keywords.text()); gui_show_playing_albumcover = reg.readBoolEntry(section_window,key_gui_show_playing_albumcover,gui_show_playing_albumcover); gui_show_albumcovers = reg.readBoolEntry(section_window,key_gui_show_albumcovers,gui_show_albumcovers); gui_tray_icon = reg.readBoolEntry(section_window,key_gui_tray_icon,gui_tray_icon); gui_show_playing_titlebar = reg.readBoolEntry(section_window,key_gui_show_playing_titlebar,gui_show_playing_titlebar); gui_show_opengl_coverview = reg.readBoolEntry(section_window,key_gui_show_opengl_coverview,gui_show_opengl_coverview); gui_coverdisplay_size = reg.readIntEntry(section_window,key_gui_coverdisplay_size,gui_coverdisplay_size); gui_format_title = reg.readStringEntry(section_window,key_gui_format_title,gui_format_title.text()); /// Player play_repeat = reg.readIntEntry(section_player,key_play_repeat,play_repeat); play_replaygain = reg.readIntEntry(section_player,key_play_replaygain,play_replaygain); play_close_stream = reg.readBoolEntry(section_player,key_play_close_stream,play_close_stream); play_pause_close_device = reg.readBoolEntry(section_player,key_play_pause_close_device,play_pause_close_device); play_gapless = reg.readBoolEntry(section_player,key_play_gapless,play_gapless); play_shuffle = reg.readBoolEntry(section_player,key_play_shuffle,play_shuffle); play_open_device_on_startup = reg.readBoolEntry(section_player,key_play_open_device_on_startup,play_open_device_on_startup); /// Dbus dbus_notify_daemon = reg.readBoolEntry(section_dbus,key_dbus_notify_daemon,dbus_notify_daemon); setKeyWords(keywords); } void GMPreferences::resetColors(){ gui_row_color=FXRGB(240,240,240); gui_play_color=FXRGB(210,230,210); gui_playtext_color=FXRGB(0,0,0); gui_tray_color=FXRGB(0,0,0); } void GMPreferences::setKeyWords(const FXString & keywords) { gui_sort_keywords.clear(); FXint numkeywords=keywords.contains(';')+1; FXString key; for (FXint i=0;igetNumItems(); if (tracklist->getSortMethod()==HEADER_QUEUE){ if (tracklist->getSortFunc()==GMDBTrackItem::descendingQueue) { for (FXint i=0;igetItem(i))->setTrackQueue(nitems-i); } } else { for (FXint i=0;igetItem(i))->setTrackQueue(i+1); } } } } void GMPlayListSource::getSelectedTrackQueues(FXIntList & list) { FXint nitems = GMPlayerManager::instance()->getTrackView()->getNumTracks(); for (FXint i=0;igetTrackView()->isTrackItemSelected(i)) list.append(((GMDBTrackItem*)GMPlayerManager::instance()->getTrackView()->getTrackItem(i))->getTrackQueue()); } } void GMPlayListSource::getTrackQueues(FXIntList & list) { FXint nitems = GMPlayerManager::instance()->getTrackView()->getNumTracks(); list.no(nitems); for (FXint i=0;igetTrackView()->getTrackItem(i))->getTrackQueue(); } } FXbool GMPlayListSource::genre_context_menu(FXMenuPane * pane) { new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove track(s) from play list."),GMIconTheme::instance()->icon_delete,this,ID_DELETE_GENRE); return true; } FXbool GMPlayListSource::artist_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy associated tracks to the clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_ARTIST); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove track(s) from play list."),GMIconTheme::instance()->icon_delete,this,ID_DELETE_ARTIST); return true; } FXbool GMPlayListSource::album_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy associated tracks to the clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_ALBUM); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove track(s) from play list."),GMIconTheme::instance()->icon_delete,this,ID_DELETE_ALBUM); return true; } FXbool GMPlayListSource::track_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Edit…\tF2\tEdit Track Information."),GMIconTheme::instance()->icon_edit,this,GMDatabaseSource::ID_EDIT_TRACK); new GMMenuCommand(pane,fxtr("Copy\tCtrl-C\tCopy track(s) to clipboard."),GMIconTheme::instance()->icon_copy,this,ID_COPY_TRACK); new FXMenuSeparator(pane); if (GMPlayerManager::instance()->getTrackView()->numTrackSelected()==1) new GMMenuCommand(pane,fxtr("Open Folder Location\t\tOpen Folder Location."),NULL,this,ID_OPEN_FOLDER); new GMMenuCommand(pane,fxtr("Remove…\tDel\tRemove track(s) from play list."),GMIconTheme::instance()->icon_delete,this,ID_DELETE_TRACK); return true; } FXbool GMPlayListSource::findCurrent(GMTrackList * list,GMSource * src) { if (src->getCurrentTrack()==-1) return false; if (src==this) { for (FXint i=0;igetNumItems();i++){ if (list->getItemId(i)==current_track && ((GMDBTrackItem*)list->getItem(i))->getTrackQueue()==current_queue) { list->setActiveItem(i); list->setCurrentItem(i); return true; } } } else { GMDatabaseSource * db = dynamic_cast(src); if (db && db->getCurrentTrack()!=-1 ) return GMSource::findCurrent(list,db); } return false; } FXbool GMPlayListSource::hasCurrentTrack(GMSource * src) const { if (src==this) return true; else if (db->trackInPlaylist(src->getCurrentTrack(),playlist)) return true; return false; } void GMPlayListSource::markCurrent(GMTrackList * list,FXint item) { current_track=-1; current_queue=-1; if (list->getNumItems()) { current_track = list->getItemId(item); current_queue = ((GMDBTrackItem*)list->getItem(item))->getTrackQueue(); } } FXbool GMPlayListSource::source_context_menu(FXMenuPane * pane){ new GMMenuCommand(pane,fxtr("Edit…"),GMIconTheme::instance()->icon_edit,this,GMPlayListSource::ID_EDIT_NAME); new GMMenuCommand(pane,fxtr("Import…"),GMIconTheme::instance()->icon_import,this,GMPlayListSource::ID_IMPORT); new GMMenuCommand(pane,fxtr("Export…"),GMIconTheme::instance()->icon_export,this,GMPlayListSource::ID_EXPORT); new GMMenuCommand(pane,fxtr("Remove Playlist"),GMIconTheme::instance()->icon_delete,this,GMPlayListSource::ID_REMOVE); return true; } FXString GMPlayListSource::getName() const{ return db->getPlaylistName(playlist); } FXbool GMPlayListSource::dnd_source_accepts(FXDragType*types,FXuint ntypes){ FXWindow * src = FXApp::instance()->getDragWindow(); for (FXuint i=0;igetSortMethod()!=HEADER_QUEUE) return false; FXint fromq = ((GMDBTrackItem*)tracklist->getItem(from))->getTrackQueue(); FXint toq = ((GMDBTrackItem*)tracklist->getItem(to))->getTrackQueue(); db->moveTrack(playlist,fromq,toq); if (current_queue==fromq) { current_queue=toq; } else if (fromq<=current_queue && current_queue<=toq) { current_queue-=1; } else if (fromq>=current_queue && current_queue>=toq) { current_queue+=1; } return true; } class FromDiskTarget : public FXObject { FXDECLARE(FromDiskTarget) protected: FXCheckButton * from_library; protected: FromDiskTarget(){} private: FromDiskTarget(const FromDiskTarget&); FromDiskTarget& operator=(const FromDiskTarget&); public: enum { ID_FROM_DISK = 1 }; public: FromDiskTarget(FXCheckButton*disk,FXCheckButton*library) : from_library(library) { disk->setTarget(this); disk->setSelector(FromDiskTarget::ID_FROM_DISK); } long onUpdFromDisk(FXObject*sender,FXSelector,void*) { if (from_library->getCheck()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } }; FXDEFMAP(FromDiskTarget) FromDiskTargetMap[]={ FXMAPFUNC(SEL_UPDATE,FromDiskTarget::ID_FROM_DISK,FromDiskTarget::onUpdFromDisk) }; FXIMPLEMENT(FromDiskTarget,FXObject,FromDiskTargetMap,ARRAYNUMBER(FromDiskTargetMap)) long GMPlayListSource::onCmdRemoveInPlaylist(FXObject*,FXSelector sel,void*){ FXIntList queue; FXIntList tracks; FXStringList files; if (FXSELID(sel)==ID_DELETE_TRACK) { getSelectedTrackQueues(queue); GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); } else { getTrackQueues(queue); GMPlayerManager::instance()->getTrackView()->getTracks(tracks); } if (tracks.no()==0) return 1; FXString title; FXString subtitle; switch(FXSELID(sel)){ case ID_DELETE_GENRE: title=fxtr("Remove Genre?"); subtitle=fxtr("Remove tracks with genre from play list?"); break; case ID_DELETE_ARTIST:title=fxtr("Remove Artist?"); subtitle=fxtr("Remove tracks from artist from play list?"); break; case ID_DELETE_ALBUM: title=fxtr("Remove Album?"); subtitle=fxtr("Remove tracks from album from play list?"); break; case ID_DELETE_TRACK: title=fxtr("Remove Track(s)?"); subtitle=fxtr("Remove track(s) from play list?"); break; default: FXASSERT(0); break; } FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),title,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,title,subtitle,NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Remove"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXCheckButton * library_check = new GMCheckButton(main,fxtr("Remove tracks from music library")); FXCheckButton * from_disk = new GMCheckButton(main,fxtr("Remove tracks from disk")); FromDiskTarget disktgt(from_disk,library_check); if (dialog.execute()){ // Check current queue... if (current_queue >= 0) { for (FXint i=0;igetCheck()) { db->beginDelete(); if (from_disk->getCheck()) getTrackFilenames(tracks,files); if (!db->removeTracks(tracks)) { FXMessageBox::error(GMPlayerManager::instance()->getMainWindow(),MBOX_OK,fxtr("Library Error"),fxtr("Unable to remove track from the library.")); } if (from_disk->getCheck()) removeFiles(files); db->endDelete(); } else { db->removeTracksFromPlaylist(queue,playlist); } GMPlayerManager::instance()->getTrackView()->refresh(); } return 1; } long GMPlayListSource::onCmdPaste(FXObject*sender,FXSelector sel,void*ptr){ GMClipboard * clipboard = GMClipboard::instance(); if (clipboard->offeredDNDType(FROM_CLIPBOARD,GMClipboard::trackdatabase)){ GMDatabaseClipboardData * clipdata = dynamic_cast(clipboard->getClipData()); if (clipdata && clipdata->tracks.no()) { db->insertTrackInPlaylist(playlist,clipdata->tracks); GMPlayerManager::instance()->getTrackView()->refresh(); } else { FXApp::instance()->beep(); } } else { return GMDatabaseSource::onCmdPaste(sender,sel,ptr); } return 1; } long GMPlayListSource::onCmdDrop(FXObject*sender,FXSelector,void*){ FXWindow * window=(FXWindow*)sender; FXString files; FXStringList filelist; FXIntList tracks; // FXbool from_kde=false; FXbool from_uri=false; FXbool from_db_all=false; FXbool from_db=false; FXDragType * types; FXuint ntypes; if (window->inquireDNDTypes(FROM_DRAGNDROP,types,ntypes)){ for (FXuint i=0;idropFinished(DRAG_ACCEPT); FXApp::instance()->beginWaitCursor(); if (from_db) GMPlayerManager::instance()->getTrackView()->getSelectedTracks(tracks); else GMPlayerManager::instance()->getTrackView()->getTracks(tracks); if (tracks.no()) db->insertTrackInPlaylist(playlist,tracks); FXApp::instance()->endWaitCursor(); return 1; } else if (from_uri) { if (window->getDNDData(FROM_DRAGNDROP,FXWindow::urilistType,files)){ gm_convert_uri_to_filenames(files,filelist); } window->dropFinished(DRAG_ACCEPT); } if (filelist.no()) { GMImportDialog dialog(GMPlayerManager::instance()->getMainWindow(),IMPORT_FROMPASTE); if (dialog.execute()) { GMPlayerManager::instance()->stop(); GMImportDatabase searchdialog(GMPlayerManager::instance()->getMainWindow(),filelist,GMPlayerManager::instance()->getPreferences().import,getPlayList(),GMPlayerManager::instance()->getMainWindow()->getThickFont()); searchdialog.execute(); GMPlayerManager::instance()->getTrackView()->refresh(); } } else { FXApp::instance()->beep(); } } return 1; } long GMPlayListSource::onCmdEditName(FXObject*,FXSelector,void *){ FXDialogBox dialog(GMPlayerManager::instance()->getMainWindow(),fxtr("Edit Playlist"),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE|DECOR_CLOSE,0,0,0,0,0,0,0,0,0,0); GMPlayerManager::instance()->getMainWindow()->create_dialog_header(&dialog,fxtr("Edit Playlist"),fxtr("Change playlist name")); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,fxtr("&Save"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,fxtr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * main = new FXVerticalFrame(&dialog,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,30,20,10,10); FXMatrix * matrix = new FXMatrix(main,2,LAYOUT_FILL_X|MATRIX_BY_COLUMNS); new FXLabel(matrix,fxtr("Name"),NULL,LABEL_NORMAL|LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXTextField * name_field = new GMTextField(matrix,20,&dialog,FXDialogBox::ID_ACCEPT,LAYOUT_FILL_X|LAYOUT_FILL_COLUMN|FRAME_SUNKEN|FRAME_THICK|TEXTFIELD_ENTER_ONLY); name_field->setText(getName()); dialog.create(); gm_focus_and_select(name_field); if (dialog.execute()) { FXString label= name_field->getText().trim(); if (!label.empty()) { db->setPlaylistName(playlist,label); GMPlayerManager::instance()->getSourceView()->updateSource(this); } } return 1; } long GMPlayListSource::onCmdRemove(FXObject*,FXSelector,void *){ if (GMPlayerManager::instance()->getMainWindow()->question(fxtr("Delete Play List?"),fxtr("Are you sure you want to delete the playlist?"),fxtr("&Yes"),fxtr("&No"))){ db->beginDelete(); db->removePlaylist(playlist); db->endDelete(); GMPlayerManager::instance()->stop(); // for now we call stop... GMPlayerManager::instance()->removeSource(this); GMPlayerManager::instance()->getSourceView()->refresh(); FXApp::instance()->reg().deleteSection(settingKey().text()); delete this; } return 1; } long GMPlayListSource::onCmdImport(FXObject*,FXSelector,void*){ GMImportDialog dialog(GMPlayerManager::instance()->getMainWindow(),IMPORT_FROMFILE|IMPORT_PLAYLIST); if (dialog.execute()){ FXString buffer; FXStringList urls; FXString title; if (gm_buffer_file(dialog.getFilename(),buffer)) { FXString extension = FXPath::extension(dialog.getFilename()); if (comparecase(extension,"m3u")==0) gm_parse_m3u(buffer,urls); else if (comparecase(extension,"pls")==0) gm_parse_pls(buffer,urls); else gm_parse_xspf(buffer,urls,title); if (urls.no()) { gm_make_absolute_path(FXPath::directory(dialog.getFilename()),urls); GMImportDatabase searchdialog(GMPlayerManager::instance()->getMainWindow(),urls,GMPlayerManager::instance()->getPreferences().import,getPlayList(),GMPlayerManager::instance()->getMainWindow()->getThickFont()); searchdialog.execute(); GMPlayerManager::instance()->getTrackView()->refresh(); } } } return 1; } gogglesmm-0.12.7/src/GMStreamSource.h0000644000175000001440000000567511525430601016117 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMSTREAMSOURCE_H #define GMSTREAMSOURCE_H class GMSource; class GMStreamSource : public GMSource { FXDECLARE(GMStreamSource) GMTrackDatabase * db; protected: GMStreamSource(); private: GMStreamSource(const GMStreamSource&); GMStreamSource& operator=(const GMStreamSource&); public: enum { ID_NEW_STATION = GMSource::ID_LAST, ID_EDIT_STATION, ID_DELETE_STATION, ID_LAST }; public: long onCmdNewStation(FXObject*,FXSelector,void*); long onCmdEditStation(FXObject*,FXSelector,void*); long onCmdDeleteStation(FXObject*,FXSelector,void*); long onUpdExport(FXObject*,FXSelector,void*); public: GMStreamSource(GMTrackDatabase * db); virtual void configure(GMColumnList&) const; FXbool hasCurrentTrack(GMSource * ) const; virtual FXbool getTrack(GMTrack & info) const; virtual FXbool setTrack(GMTrack & info) const; FXString getTrackFilename(FXint id) const; FXString getName() const { return notr("Internet Radio"); } FXint getType() const { return SOURCE_INTERNET_RADIO; } FXString settingKey() const { return "internet-radio"; } FXint getSortColumn(FXbool) const { return HEADER_TRACK; } FXbool canBrowse() const { return false; } FXbool defaultBrowse() const { return false; } FXbool autoPlay() const { return false; } FXbool source_context_menu(FXMenuPane * pane); FXbool track_context_menu(FXMenuPane * pane); FXbool listTracks(GMTrackList * tracklist,const FXIntList & albumlist,const FXIntList & genrelist); virtual ~GMStreamSource(); }; #endif gogglesmm-0.12.7/src/GMWindow.cpp0000644000175000001440000016221111616526316015305 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include #include #include #include "GMPlayer.h" #include "GMApp.h" #include "GMAbout.h" #include "GMWindow.h" #include "GMTrackList.h" #include "GMList.h" #include "GMRemote.h" #include "GMTag.h" #include "GMThread.h" #include "GMSearch.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMDatabaseSource.h" #include "GMTrackView.h" #include "GMSourceView.h" #include "GMAudioScrobbler.h" #include "icons.h" #include "GMIconTheme.h" #include "GMImportDialog.h" #include "GMPreferencesDialog.h" #include "GMImageView.h" #include "GMFilename.h" #include #include #include #include #include #include #if FOXVERSION > FXVERSION(1,7,21) #define HIDESOURCES (FX4Splitter::ExpandTopRight) #define SHOWSOURCES (FX4Splitter::ExpandTopLeft|FX4Splitter::ExpandTopRight) #define SHOWSOURCES_COVER (FX4Splitter::ExpandTopLeft|FX4Splitter::ExpandTopRight|FX4Splitter::ExpandBottomLeft) #endif // Define Message Map FXDEFMAP(GMWindow) GMWindowMap[]={ //________Message_Type_____________________ID___________________________Message_Handler___ FXMAPFUNC(SEL_UPDATE, GMWindow::ID_PLAYPAUSE, GMWindow::onUpdPlayPause), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_PLAYPAUSEMENU, GMWindow::onUpdPlayPauseMenu), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_PAUSE, GMWindow::onUpdPause), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_STOP, GMWindow::onUpdStop), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_NEXT, GMWindow::onUpdNext), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_PREV, GMWindow::onUpdPrev), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_REPEAT_ALL, GMWindow::onUpdRepeatAll), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_REPEAT, GMWindow::onUpdRepeat), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_REPEAT_AB, GMWindow::onUpdRepeatAB), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_REPEAT_OFF, GMWindow::onUpdRepeatOff), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_SHUFFLE, GMWindow::onUpdShuffle), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_SLEEP, GMWindow::onUpdSleepTimer), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_SHOW_TRACK, GMWindow::onUpdShowTrack), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_VOLUME_BUTTON, GMWindow::onUpdVolumeButton), FXMAPFUNC(SEL_UPDATE, GMWindow::ID_SHOW_MINIPLAYER, GMWindow::onUpdShowMiniPlayer), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_QUIT, GMWindow::onCmdQuit), FXMAPFUNC(SEL_SIGNAL, GMWindow::ID_QUIT, GMWindow::onCmdQuit), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_IMPORT_DIRS, GMWindow::onCmdImport), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_IMPORT_FILES, GMWindow::onCmdImport), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SYNC_DIRS, GMWindow::onCmdImport), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_OPEN, GMWindow::onCmdOpen), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_REPEAT_ALL, GMWindow::onCmdRepeatAll), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_REPEAT_AB, GMWindow::onCmdRepeatAB), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_REPEAT, GMWindow::onCmdRepeat), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_REPEAT_OFF, GMWindow::onCmdRepeatOff), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SHUFFLE, GMWindow::onCmdShuffle), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_ABOUT, GMWindow::onCmdAbout), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_PLAYPAUSE, GMWindow::onCmdPlayPause), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_PLAYPAUSEMENU, GMWindow::onCmdPlayPause), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_PAUSE, GMWindow::onCmdPause), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_STOP, GMWindow::onCmdStop), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_NEXT, GMWindow::onCmdNext), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_PREV, GMWindow::onCmdPrev), #if FOXVERSION >= FXVERSION(1,7,11) FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SHOW_FULLSCREEN, GMWindow::onCmdShowFullScreen), #endif FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SHOW_MINIPLAYER, GMWindow::onCmdShowMiniPlayer), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SHOW_TRACK, GMWindow::onCmdShowTrack), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_PREFERENCES, GMWindow::onCmdPreferences), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_RESET_COLORS, GMWindow::onCmdResetColors), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_TIMESLIDER, GMWindow::onCmdTimeSlider), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_VOLUME_SLIDER, GMWindow::onCmdVolume), FXMAPFUNC(SEL_CHANGED, GMWindow::ID_VOLUME_SLIDER, GMWindow::onCmdVolume), FXMAPFUNC(SEL_MOUSEWHEEL, GMWindow::ID_VOLUME_BUTTON, GMWindow::onCmdVolumeButton), FXMAPFUNC(SEL_MOUSEWHEEL, 0, GMWindow::onCmdVolumeButton), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_HOMEPAGE, GMWindow::onCmdHomePage), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_REPORT_ISSUE, GMWindow::onCmdReportIssue), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_JOIN_LASTFM, GMWindow::onCmdJoinLastFM), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_JOIN_GMM_LASTFM, GMWindow::onCmdJoinGMMLastFM), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SLEEP, GMWindow::onCmdSleepTimer), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_CHANGE_COVERVIEW, GMWindow::onCmdChangeCoverView), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, GMWindow::ID_COVERVIEW, GMWindow::onCmdCoverView), #if FOXVERSION > FXVERSION(1,7,21) FXMAPFUNC(SEL_UPDATE, GMWindow::ID_SHOW_SOURCES, GMWindow::onUpdShowSources), FXMAPFUNC(SEL_COMMAND, GMWindow::ID_SHOW_SOURCES, GMWindow::onCmdShowSources), #endif FXMAPFUNCS(SEL_COMMAND, GMWindow::ID_COVERSIZE_SMALL,GMWindow::ID_COVERSIZE_EXTRALARGE, GMWindow::onCmdCoverSize), FXMAPFUNCS(SEL_UPDATE, GMWindow::ID_COVERSIZE_SMALL,GMWindow::ID_COVERSIZE_EXTRALARGE, GMWindow::onUpdCoverSize), }; // Object implementation FXIMPLEMENT(GMWindow,FXMainWindow,GMWindowMap,ARRAYNUMBER(GMWindowMap)) //---------------------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------------------- GMWindow::GMWindow(FXApp* a,FXObject*tgt,FXSelector msg) : FXMainWindow(a,"Goggles Music Manager",NULL,NULL,DECOR_ALL,5,5,700,580) { flags|=FLAG_ENABLED; remote=NULL; cover_small=NULL; icontheme = new GMIconTheme(getApp()); icontheme->load(); createFonts(); setIcon(icontheme->icon_applogo); setMiniIcon(icontheme->icon_applogo_small); #if APPLICATION_BETA > 0 setTitle("Goggles Music Manager " APPLICATION_VERSION_STRING); #endif /// Set myself as the target setTarget(tgt); setSelector(msg); /// Popup Volume Menu volumecontrol = new FXPopup(this,POPUP_VERTICAL|FRAME_RAISED|FRAME_THICK|POPUP_SHRINKWRAP); volumeslider = new FXSlider(volumecontrol,this,GMWindow::ID_VOLUME_SLIDER,LAYOUT_FIX_HEIGHT|LAYOUT_FIX_WIDTH|SLIDER_VERTICAL|SLIDER_TICKS_RIGHT|SLIDER_TICKS_LEFT|SLIDER_INSIDE_BAR,0,0,20,100); volumeslider->setTickDelta(10); volumeslider->setRange(0,100); volumeslider->setIncrement(10); // Make menu bar FXMenuBar * menubar=new FXMenuBar(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X); menubar->setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); statusbar = new FXStatusBar(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER,0,0,0,0,3,3,2,2,3); statusbar->getStatusLine()->setFrameStyle(FRAME_NONE); new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_TOP); // controlstatusseparator = new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM); // controlstatusseparator->hide(); controlseparator = new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM); controlframe = new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X,0,0,0,0,3,3,3,3); playpausebutton = new FXToggleButton(controlframe,tr("Play\tStart Playback\tStart Playback"),tr("Pause\tPause\tPause Playback"),icontheme->icon_play,icontheme->icon_pause,this,ID_PLAYPAUSE,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); stopbutton = new FXButton(controlframe,tr("Stop\tStop Playback\tStop Playback"),icontheme->icon_stop,this,ID_STOP,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXVerticalSeparator(controlframe,LAYOUT_FILL_Y|SEPARATOR_GROOVE); prevbutton = new FXButton(controlframe,tr("Previous\tPlay Previous Track\tPlay previous track."),icontheme->icon_prev,this,ID_PREV,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); nextbutton = new FXButton(controlframe,tr("Next\tPlay Next Track\tPlay next track."),icontheme->icon_next,this,ID_NEXT,BUTTON_TOOLBAR|FRAME_RAISED|ICON_ABOVE_TEXT); new FXVerticalSeparator(controlframe,LAYOUT_FILL_Y|SEPARATOR_GROOVE); timeslider = new FXSlider(controlframe,this,ID_TIMESLIDER,LAYOUT_FILL_X|LAYOUT_CENTER_Y); timeslider->setRange(0,65535); timeslider->setTickDelta(13107); timeslider->setIncrement(5000); timeslider->disable(); timelabel =new FX7Segment(controlframe,"--:--",SEVENSEGMENT_SHADOW|LAYOUT_CENTER_Y); timelabel->setCellWidth(10); timelabel->setCellHeight(15); new FXVerticalSeparator(controlframe,LAYOUT_FILL_Y|SEPARATOR_GROOVE); volumebutton = new FXMenuButton(controlframe,tr("\tAdjust Volume\tAdjust Volume"),NULL,volumecontrol,MENUBUTTON_NOARROWS|MENUBUTTON_ATTACH_LEFT|MENUBUTTON_UP|MENUBUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y); volumebutton->setTarget(this); volumebutton->setSelector(ID_VOLUME_BUTTON); controldragcorner = new FXDragCorner(controlframe); FXVerticalFrame * mainframe = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y); #if FOXVERSION > FXVERSION(1,7,21) mainsplitter = new FX4Splitter(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y|FOURSPLITTER_VERTICAL|FOURSPLITTER_TRACKING); sourceview = new GMSourceView(mainsplitter); trackview = new GMTrackView(mainsplitter); coverframe = new GMCoverFrame(mainsplitter); #else mainsplitter = new FXSplitter(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_HORIZONTAL|SPLITTER_TRACKING); sourcesplitter = new FXSplitter(mainsplitter,LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_TRACKING|SPLITTER_REVERSED); sourceview = new GMSourceView(sourcesplitter); coverframe = new GMCoverFrame(sourcesplitter); trackview = new GMTrackView(mainsplitter); sourcesplitter->setBarSize(7); #endif mainsplitter->setBarSize(7); coverframe->setBackColor(getApp()->getBackColor()); coverframe->setBorderColor(getApp()->getShadowColor()); coverframe->hide(); coverview_x11=NULL; coverview_gl=NULL; glvisual=NULL; updateCoverView(); // File Menu filemenu=new GMMenuPane(this); new GMMenuTitle(menubar,tr("&Music"),NULL,filemenu); new GMMenuCommand(filemenu,tr("Import Folder…\tCtrl-O\tImport Music from folder into Library"),icontheme->icon_import,this,GMWindow::ID_IMPORT_DIRS); new GMMenuCommand(filemenu,tr("Sync Folder…\t\tSynchronize Folder with Music in Library"),icontheme->icon_sync,this,GMWindow::ID_SYNC_DIRS); new FXMenuSeparator(filemenu); new GMMenuCommand(filemenu,tr("Play File or Stream…\t\tPlay File or Stream"),NULL,this,GMWindow::ID_OPEN); new FXMenuSeparator(filemenu); new GMMenuCommand(filemenu,tr("New Playlist…\t\tCreate a new playlist"),icontheme->icon_playlist,sourceview,GMSourceView::ID_NEW_PLAYLIST); new GMMenuCommand(filemenu,tr("Import Playlist…\t\tImport existing playlist"),icontheme->icon_import,GMPlayerManager::instance()->getDatabaseSource(),GMDatabaseSource::ID_IMPORT_PLAYLIST); new GMMenuCommand(filemenu,tr("New Radio Station…\t\tCreate a new playlist"),NULL,sourceview,GMSourceView::ID_NEW_STATION); new FXMenuSeparator(filemenu); new GMMenuCommand(filemenu,tr("&Quit\tCtrl-Q\tQuit the application."),icontheme->icon_exit,this,GMWindow::ID_QUIT); gm_set_window_cursor(filemenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); // Help Menu editmenu=new GMMenuPane(this); new GMMenuTitle(menubar,tr("&Edit"),NULL,editmenu); new GMMenuCommand(editmenu,tr("&Copy\tCtrl-C\tCopy Selected Tracks"),icontheme->icon_copy,trackview,GMTrackView::ID_COPY,MENU_AUTOGRAY); new GMMenuCommand(editmenu,tr("&Cut\tCtrl-X\tCut Selected Tracks"),icontheme->icon_cut,trackview,GMTrackView::ID_CUT,MENU_AUTOGRAY); new GMMenuCommand(editmenu,tr("&Paste\tCtrl-V\tPaste Clipboard Selection"),icontheme->icon_paste,trackview,GMTrackView::ID_PASTE,MENU_AUTOGRAY); new FXMenuSeparator(editmenu); new GMMenuCommand(editmenu,tr("Find…\tCtrl-F\tShow search filter."),GMIconTheme::instance()->icon_find,trackview,GMTrackView::ID_TOGGLE_FILTER); new FXMenuSeparator(editmenu); new GMMenuCommand(editmenu,tr("Preferences…"),icontheme->icon_settings,this,GMWindow::ID_PREFERENCES); gm_set_window_cursor(editmenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); viewmenu=new GMMenuPane(this); new GMMenuTitle(menubar,tr("&View"),NULL,viewmenu); new GMMenuCheck(viewmenu,tr("&Browse\tCtrl-B\tShow genre artist and album browser."),trackview,GMTrackView::ID_TOGGLE_BROWSER); new GMMenuCheck(viewmenu,tr("Show &Genres\tCtrl-G\tShow genre browser."),trackview,GMTrackView::ID_TOGGLE_GENRES); new FXMenuSeparator(viewmenu); #if FOXVERSION > FXVERSION(1,7,21) new GMMenuCheck(viewmenu,tr("Show &Sources\tCtrl-S\tShow source browser "),this,ID_SHOW_SOURCES); #else new GMMenuCheck(viewmenu,tr("Show &Sources\tCtrl-S\tShow source browser "),sourcesplitter,FXWindow::ID_TOGGLESHOWN); #endif new FXMenuSeparator(viewmenu); #if FOXVERSION >= FXVERSION(1,7,11) fullscreencheck = new GMMenuCheck(viewmenu,tr("Show Full Screen\tF12\tToggle fullscreen mode."),this,ID_SHOW_FULLSCREEN); #endif new GMMenuCheck(viewmenu,tr("Show Mini Player\tCtrl-M\tToggle Mini Player."),this,ID_SHOW_MINIPLAYER); new FXMenuSeparator(viewmenu); new GMMenuCommand(viewmenu,tr("&Configure Columns…"),NULL,trackview,GMTrackView::ID_CONFIGURE_COLUMNS); new GMMenuCascade(viewmenu,tr("&Sort"),icontheme->icon_sort,trackview->getSortMenu()); new FXMenuSeparator(viewmenu); new GMMenuCommand(viewmenu,tr("&Jump to Current Track\tCtrl-J\tShow current playing track."),NULL,trackview,GMTrackView::ID_SHOW_CURRENT); gm_set_window_cursor(viewmenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); playmenu=new GMMenuPane(this); new GMMenuTitle(menubar,tr("&Control"),NULL,playmenu); new GMMenuCommand(playmenu,tr("Play\tCtrl-P\tStart playback."),icontheme->icon_play,this,ID_PLAYPAUSEMENU); new GMMenuCommand(playmenu,tr("Stop\tCtrl-\\\tStop playback."),icontheme->icon_stop,this,ID_STOP); new GMMenuCommand(playmenu,tr("Previous Track\tCtrl-[\tPlay next track."),icontheme->icon_prev,this,ID_PREV); new GMMenuCommand(playmenu,tr("Next Track\tCtrl-]\tPlay previous track."),icontheme->icon_next,this,ID_NEXT); new FXMenuSeparator(playmenu); new GMMenuRadio(playmenu,tr("Repeat Off\tCtrl-,\tRepeat current track."),this,ID_REPEAT_OFF); new GMMenuRadio(playmenu,tr("Repeat Track\tCtrl-.\tRepeat current track."),this,ID_REPEAT); new GMMenuRadio(playmenu,tr("Repeat All Tracks\tCtrl-/\tRepeat all tracks."),this,ID_REPEAT_ALL); new GMMenuCheck(playmenu,tr("Repeat A-B\tCtrl-T\tRepeat section of track."),this,ID_REPEAT_AB); new GMMenuCheck(playmenu,tr("Shuffle Mode\tAlt-R\tPlay tracks in random order."),this,ID_SHUFFLE); new FXMenuSeparator(playmenu); new GMMenuCommand(playmenu,tr("Equalizer\t\t"),NULL,GMPlayerManager::instance(),GMPlayerManager::ID_EQUALIZER); new GMMenuCheck(playmenu,tr("Sleep Timer\t\tSetup sleeptimer."),this,ID_SLEEP); gm_set_window_cursor(playmenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); helpmenu=new GMMenuPane(this); new GMMenuTitle(menubar,tr("&Help"),NULL,helpmenu,LAYOUT_RIGHT); new GMMenuCommand(helpmenu,tr("&Homepage"),icontheme->icon_homepage,this,GMWindow::ID_HOMEPAGE); new GMMenuCommand(helpmenu,tr("&Report Issue…"),NULL,this,GMWindow::ID_REPORT_ISSUE); new FXMenuSeparator(helpmenu); new GMMenuCommand(helpmenu,tr("&Sign up for last.fm…"),NULL,this,GMWindow::ID_JOIN_LASTFM); new GMMenuCommand(helpmenu,tr("&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…"),NULL,this,GMWindow::ID_JOIN_GMM_LASTFM); new FXMenuSeparator(helpmenu); new GMMenuCommand(helpmenu,tr("&About…"),icontheme->icon_info,this,GMWindow::ID_ABOUT); gm_set_window_cursor(helpmenu,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); getAccelTable()->addAccel(parseAccel("F11"),this,FXSEL(SEL_COMMAND,ID_SHOW_MINIPLAYER)); getAccelTable()->addAccel(parseAccel("Ctrl-W"),this,FXSEL(SEL_CLOSE,0)); getAccelTable()->addAccel(parseAccel("/"),trackview,FXSEL(SEL_COMMAND,GMTrackView::ID_TOGGLE_FILTER)); } void GMWindow::init(FXuint mode) { sourceview->init(); if (mode==SHOW_NORMAL || mode==SHOW_TRAY) { if (getApp()->reg().readBoolEntry("window","remote",false)){ if (!remote) { remote = new GMRemote(getApp(),target,message); remote->create(); } } } switch(mode) { case SHOW_TRAY : break; case SHOW_WIZARD: toggleShown(); handle(this,FXSEL(SEL_COMMAND,GMWindow::ID_IMPORT_DIRS),NULL); break; default : if (getApp()->reg().readBoolEntry("window","window-show",true)){ toggleShown(); } break; }; } //---------------------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------------------- GMWindow::~GMWindow(){ if (coverview_gl) { coverview_gl->setImage(NULL); delete coverview_gl; delete glvisual; } delete icontheme; } //---------------------------------------------------------------------------------- // Create Fonts //---------------------------------------------------------------------------------- void GMWindow::createFonts(){ #if FOXVERSION < FXVERSION(1,7,17) FXFontDesc fontdescription; getApp()->getNormalFont()->getFontDesc(fontdescription); #else FXFontDesc fontdescription = getApp()->getNormalFont()->getFontDesc(); #endif fontdescription.weight = FXFont::Bold; font_thick = new FXFont(getApp(),fontdescription); font_thick->create(); } //---------------------------------------------------------------------------------- // Create //---------------------------------------------------------------------------------- void GMWindow::create(){ #if FOXVERSION > FXVERSION(1,7,21) mainsplitter->setHSplit(getApp()->reg().readIntEntry("window","source-list-hsplit",2500)); #else mainsplitter->setSplit(0,getApp()->reg().readIntEntry("window","source-list-split",200)); sourcesplitter->setSplit(1,getApp()->reg().readIntEntry("window","cover-list-split",256+10+2)); #endif configureStatusbar(GMPlayerManager::instance()->getPreferences().gui_show_status_bar); /// Set initial Toolbar Configuration configureToolbar(GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop, GMPlayerManager::instance()->getPreferences().gui_toolbar_showlabels, GMPlayerManager::instance()->getPreferences().gui_toolbar_bigicons, true); FXMainWindow::create(); fix_wm_properties(this); /// Initialize the window size & position if (getApp()->reg().readIntEntry("window","x",-1)!=-1) { FXint xx=getApp()->reg().readIntEntry("window","x",getX()); FXint yy=getApp()->reg().readIntEntry("window","y",getY()); FXint ww=getApp()->reg().readIntEntry("window","width",500); FXint hh=getApp()->reg().readIntEntry("window","height",550); position(xx,yy,ww,hh); } else { place(PLACEMENT_SCREEN); } /// Set Window Type to Normal ewmh_change_window_type(this,WINDOWTYPE_NORMAL); /// Set extended window manager hints on the menus for compositing window managers. ewmh_change_window_type(filemenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(editmenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(viewmenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(playmenu,WINDOWTYPE_DROPDOWN_MENU); ewmh_change_window_type(helpmenu,WINDOWTYPE_DROPDOWN_MENU); gm_set_application_icon(this); } #if FOXVERSION >= FXVERSION(1,7,11) void GMWindow::setFullScreen(FXbool show){ if (show) { if (isMaximized()) restore(); getApp()->reg().writeIntEntry("window","x",getX()); getApp()->reg().writeIntEntry("window","y",getY()); getApp()->reg().writeIntEntry("window","width",getWidth()); getApp()->reg().writeIntEntry("window","height",getHeight()); fullScreen(); statusbar->setCornerStyle(false); controldragcorner->hide(); fullscreencheck->setCheck(true); } else { restore(); if (!statusbar->shown() && GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop==false) controldragcorner->show(); statusbar->setCornerStyle(true); fullscreencheck->setCheck(false); } } #endif void GMWindow::hide() { #if FOXVERSION >= FXVERSION(1,7,11) getApp()->reg().writeBoolEntry("window","fullscreen",isFullScreen()); #endif getApp()->reg().writeBoolEntry("window","maximized",isMaximized()); #if FOXVERSION >= FXVERSION(1,7,11) if (isFullScreen() || isMaximized() || isMinimized() ) #else if (isMaximized() || isMinimized() ) #endif restore(); FXMainWindow::hide(); } void GMWindow::toggleShown() { if (remote) { if (remote->shown()) remote->hide(); else remote->show(); } else { if (shown()) hide(); else show(); } } void GMWindow::show(){ FXMainWindow::show(); #if FOXVERSION >= FXVERSION(1,7,11) if (getApp()->reg().readBoolEntry("window","fullscreen",false)){ getApp()->reg().writeBoolEntry("window","fullscreen",false); getApp()->reg().writeBoolEntry("window","maximized",false); if (getApp()->reg().readIntEntry("window","x",-1)!=-1) { FXint xx=getApp()->reg().readIntEntry("window","x",getX()); FXint yy=getApp()->reg().readIntEntry("window","y",getY()); FXint ww=getApp()->reg().readIntEntry("window","width",500); FXint hh=getApp()->reg().readIntEntry("window","height",550); position(xx,yy,ww,hh); } else { place(PLACEMENT_SCREEN); } setFullScreen(true); } else #endif if (getApp()->reg().readBoolEntry("window","maximized",false)){ getApp()->reg().writeBoolEntry("window","fullscreen",false); getApp()->reg().writeBoolEntry("window","maximized",false); maximize(); } } FXbool GMWindow::question(const FXString & title,const FXString & labeltext,const FXString & accept,const FXString & cancel){ FXDialogBox dialog(this,title,DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE,0,0,400,0,0,0,0,0,0,0); create_dialog_header(&dialog,title,labeltext,NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_BOTTOM|LAYOUT_FILL_X,0,0,0,0); new GMButton(closebox,accept,NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); new GMButton(closebox,cancel,NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); if (dialog.execute()) { return TRUE; } return FALSE; } void GMWindow::showRemote(){ if (!remote) { remote = new GMRemote(getApp(),target,message); remote->update_volume_display(GMPlayerManager::instance()->volume()); remote->create(); if (GMPlayerManager::instance()->playing()){ GMTrack info; GMPlayerManager::instance()->getTrackInformation(info); remote->updateCover(cover_small); remote->display(info); } remote->show(); } } void GMWindow::hideRemote(){ if (remote) { remote->writeRegistry(); delete remote; remote = NULL; } show(); } void GMWindow::reset() { if (remote) remote->reset(); /// Reset Status Text statusbar->getStatusLine()->setNormalText("Ready."); /// Clear Cover loadCover(FXString::null); #if APPLICATION_BETA > 0 setTitle("Goggles Music Manager " APPLICATION_VERSION_STRING); #else setTitle("Goggles Music Manager"); #endif } void GMWindow::display(const GMTrack& info){ FXUTF8Codec codec; FXString title = GMFilename::format_track(info,GMPlayerManager::instance()->getPreferences().gui_format_title,FXString::null,0,&codec); statusbar->getStatusLine()->setNormalText(title); if (GMPlayerManager::instance()->getPreferences().gui_show_playing_titlebar){ #if APPLICATION_BETA > 0 setTitle(GMStringFormat("%s ~ Goggles Music Manager " APPLICATION_VERSION_STRING,title.text())); #else setTitle(GMStringFormat("%s ~ Goggles Music Manager",title.text())); #endif } else { #if APPLICATION_BETA > 0 setTitle("Goggles Music Manager " APPLICATION_VERSION_STRING); #else setTitle("Goggles Music Manager"); #endif } if (remote) remote->display(info); } void GMWindow::update_volume_display(FXint level) { if (level<=0) volumebutton->setIcon(icontheme->icon_audio_volume_muted); else if (level<=33) volumebutton->setIcon(icontheme->icon_audio_volume_low); else if (level<=66) volumebutton->setIcon(icontheme->icon_audio_volume_medium); else volumebutton->setIcon(icontheme->icon_audio_volume_high); volumeslider->setValue(level); if (remote) remote->update_volume_display(level); } void GMWindow::update_elapsed_time(FXint hours,FXint minutes,FXint seconds,FXint position,FXbool playing,FXbool seekable) { if (playing) { if (hours>0) timelabel->setText(GMStringFormat("%d:%.2d:%.2d",hours,minutes,seconds)); else timelabel->setText(GMStringFormat("%.2d:%.2d",minutes,seconds)); if (seekable) { if (!timeslider->grabbed()){ timeslider->setValue(position); timeslider->enable(); } } else { timeslider->disable(); } } else { timelabel->setText("--:--"); timeslider->disable(); } if (remote) remote->elapsed_time(hours,minutes,seconds,position,playing); } long GMWindow::onCmdQuit(FXObject *,FXSelector,void*){ sourceview->saveView(); trackview->saveView(); /// Save the Window State getApp()->reg().writeBoolEntry("window","remote",(remote==NULL) ? false : true); if (remote) getApp()->reg().writeBoolEntry("window","window-show",remote->shown()); else getApp()->reg().writeBoolEntry("window","window-show",shown()); #if FOXVERSION >= FXVERSION(1,7,11) if (!isFullScreen() && !isMaximized() && !isMinimized() &&shown()) { #else if (!isMaximized() && !isMinimized() && shown()) { #endif getApp()->reg().writeIntEntry("window","x",getX()); getApp()->reg().writeIntEntry("window","y",getY()); getApp()->reg().writeIntEntry("window","width",getWidth()); getApp()->reg().writeIntEntry("window","height",getHeight()); } #if FOXVERSION >= FXVERSION(1,7,11) getApp()->reg().writeBoolEntry("window","fullscreen",isFullScreen()); #endif getApp()->reg().writeBoolEntry("window","maximized",isMaximized()); #if FOXVERSION > FXVERSION(1,7,21) getApp()->reg().writeIntEntry("window","source-list-hsplit",mainsplitter->getHSplit()); #else getApp()->reg().writeIntEntry("window","source-list-split",mainsplitter->getSplit(0)); getApp()->reg().writeIntEntry("window","cover-list-split",sourcesplitter->getSplit(1)); #endif /// Get rid of remote if (remote) { remote->writeRegistry(); delete remote; remote = NULL; } volumeslider->setTarget(NULL); volumeslider->setSelector(0); volumebutton->setMenu(NULL); delete volumecontrol; GMPlayerManager::instance()->exit(); return 1; } long GMWindow::onCmdAbout(FXObject *,FXSelector,void*){ GMAboutDialog dialog(this); dialog.execute(PLACEMENT_SCREEN); return 1; } #if FOXVERSION >= FXVERSION(1,7,11) long GMWindow::onCmdShowFullScreen(FXObject*,FXSelector,void*){ if (isFullScreen()) { setFullScreen(false); } else { setFullScreen(true); } return 1; } #endif long GMWindow::onCmdShowMiniPlayer(FXObject*,FXSelector,void*){ showRemote(); hide(); return 1; } long GMWindow::onUpdShowMiniPlayer(FXObject*sender,FXSelector,void*){ if (remote) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); return 1; } long GMWindow::onCmdShowTrack(FXObject *,FXSelector,void*){ return 1; } long GMWindow::onUpdShowTrack(FXObject *sender,FXSelector,void*){ if (!GMPlayerManager::instance()->playing()) sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); return 1; } long GMWindow::onCmdResetColors(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPreferences().resetColors(); return 1; } long GMWindow::onCmdPreferences(FXObject *,FXSelector,void*){ GMPreferencesDialog dialog(this); dialog.execute(); return 1; } void GMWindow::configureStatusbar(FXbool show){ if (show) { statusbar->show(); //controlstatusseparator->show(); controldragcorner->hide(); } else { statusbar->hide(); //controlstatusseparator->hide(); if (!GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop){ controldragcorner->show(); controlframe->recalc(); } } GMPlayerManager::instance()->getPreferences().gui_show_status_bar=show; recalc(); controlframe->recalc(); } void GMWindow::layoutToolBarButtons() { if (GMPlayerManager::instance()->getPreferences().gui_toolbar_showlabels) { FXint mw = playpausebutton->getDefaultWidth(); mw = FXMAX(mw,stopbutton->getDefaultWidth()); mw = FXMAX(mw,prevbutton->getDefaultWidth()); mw = FXMAX(mw,nextbutton->getDefaultWidth()); playpausebutton->setLayoutHints(LAYOUT_FIX_WIDTH); playpausebutton->setWidth(mw); stopbutton->setLayoutHints(LAYOUT_FIX_WIDTH); stopbutton->setWidth(mw); prevbutton->setLayoutHints(LAYOUT_FIX_WIDTH); prevbutton->setWidth(mw); nextbutton->setLayoutHints(LAYOUT_FIX_WIDTH); nextbutton->setWidth(mw); } else { playpausebutton->setLayoutHints(0); stopbutton->setLayoutHints(0); prevbutton->setLayoutHints(0); nextbutton->setLayoutHints(0); } } void GMWindow::configureToolbar(FXbool docktop,FXbool showlabels,FXbool bigicons,FXbool init/*=false*/){ // if ((docktop != GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop) || init) { if (docktop) { controlframe->setLayoutHints(LAYOUT_FILL_X|LAYOUT_SIDE_TOP); //controlseparator->setLayoutHints(LAYOUT_FILL_X|LAYOUT_SIDE_TOP); controldragcorner->hide(); controlseparator->hide(); } else { controlframe->setLayoutHints(LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); //controlseparator->setLayoutHints(LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); if (!statusbar->shown()) controldragcorner->show(); if (statusbar->shown()) controlseparator->show(); else controlseparator->hide(); } // } if ((bigicons != GMPlayerManager::instance()->getPreferences().gui_toolbar_bigicons) || init) { if (bigicons) { playpausebutton->setIcon(icontheme->icon_play_toolbar); playpausebutton->setAltIcon(icontheme->icon_pause_toolbar); stopbutton->setIcon(icontheme->icon_stop_toolbar); prevbutton->setIcon(icontheme->icon_prev_toolbar); nextbutton->setIcon(icontheme->icon_next_toolbar); } else { playpausebutton->setIcon(icontheme->icon_play); playpausebutton->setAltIcon(icontheme->icon_pause); stopbutton->setIcon(icontheme->icon_stop); prevbutton->setIcon(icontheme->icon_prev); nextbutton->setIcon(icontheme->icon_next); } update_volume_display(GMPlayerManager::instance()->volume()); } if (showlabels != GMPlayerManager::instance()->getPreferences().gui_toolbar_showlabels || init) { if (showlabels) { playpausebutton->setText(tr("Play")); playpausebutton->setAltText(tr("Pause")); stopbutton->setText(tr("Stop")); prevbutton->setText(tr("Previous")); nextbutton->setText(tr("Next")); } else { playpausebutton->setText(FXString::null); playpausebutton->setAltText(FXString::null); stopbutton->setText(FXString::null); prevbutton->setText(FXString::null); nextbutton->setText(FXString::null); } GMPlayerManager::instance()->getPreferences().gui_toolbar_showlabels=showlabels; layoutToolBarButtons(); } GMPlayerManager::instance()->getPreferences().gui_toolbar_docktop=docktop; GMPlayerManager::instance()->getPreferences().gui_toolbar_bigicons=bigicons; } long GMWindow::onCmdImport(FXObject *,FXSelector sel,void*){ FXuint mode=(FXSELID(sel)==ID_IMPORT_DIRS || FXSELID(sel)==ID_SYNC_DIRS) ? IMPORT_FROMDIR : IMPORT_FROMFILE; if (FXSELID(sel)==ID_SYNC_DIRS) mode|=IMPORT_SYNC; GMImportDialog dialog(this,mode); if (dialog.execute()) { FXStringList files; dialog.getSelectedFiles(files); GMPlayerManager::instance()->stop(); if (FXSELID(sel)==ID_SYNC_DIRS) { GMSyncDatabase searchdialog(this,files,GMPlayerManager::instance()->getPreferences().import,GMPlayerManager::instance()->getPreferences().sync,-1,true,font_thick); searchdialog.execute(); } else { GMImportDatabase searchdialog(this,files,GMPlayerManager::instance()->getPreferences().import,-1,font_thick); searchdialog.execute(); } if (sourceview->getSource()==GMPlayerManager::instance()->getSource(0)) trackview->refresh(); } return 1; } long GMWindow::onCmdPlayPause(FXObject*,FXSelector,void*){ if (GMPlayerManager::instance()->can_pause()) GMPlayerManager::instance()->pause(); else if (GMPlayerManager::instance()->can_unpause()) GMPlayerManager::instance()->unpause(); else GMPlayerManager::instance()->play(); return 1; } long GMWindow::onUpdPlayPause(FXObject*sender,FXSelector,void*){ if ( GMPlayerManager::instance()->can_play() || GMPlayerManager::instance()->can_unpause() || GMPlayerManager::instance()->can_pause()){ sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); if (GMPlayerManager::instance()->can_play() || GMPlayerManager::instance()->can_unpause()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),NULL); } else { sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),NULL); } return 1; } long GMWindow::onUpdPlayPauseMenu(FXObject*sender,FXSelector,void*){ FXMenuCommand * menucommand=dynamic_cast(sender); FXButton * button=dynamic_cast(sender); if ( GMPlayerManager::instance()->can_play() || GMPlayerManager::instance()->can_unpause() || GMPlayerManager::instance()->can_pause()){ if (GMPlayerManager::instance()->can_play() || GMPlayerManager::instance()->can_unpause()){ if (button) { button->enable(); button->setHelpText(tr("Start playback.")); button->setIcon(GMIconTheme::instance()->icon_play); } else { menucommand->enable(); menucommand->setText(tr("Play")); menucommand->setHelpText(tr("Start playback")); menucommand->setTipText(tr("Start playback")); menucommand->setIcon(GMIconTheme::instance()->icon_play); } } else { if (button) { button->enable(); button->setHelpText(tr("Pause playback.")); button->setTipText(tr("Pause playback")); button->setIcon(GMIconTheme::instance()->icon_pause); } else { menucommand->enable(); menucommand->setText(tr("Pause")); menucommand->setHelpText(tr("Pause playback.")); menucommand->setIcon(GMIconTheme::instance()->icon_pause); } } } else { if (button) { button->setHelpText(tr("Start playback.")); button->setIcon(GMIconTheme::instance()->icon_play); button->disable(); } else { menucommand->setText(tr("Play")); menucommand->setHelpText(tr("Start playback.")); menucommand->setIcon(GMIconTheme::instance()->icon_play); menucommand->disable(); } } return 1; } long GMWindow::onCmdPause(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->pause(); return 1; } long GMWindow::onUpdPause(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->can_pause()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_SHOW),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_HIDE),NULL); return 1; } long GMWindow::onCmdStop(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->stop(); return 1; } long GMWindow::onUpdStop(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->can_stop()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMWindow::onCmdNext(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->next(); return 1; } long GMWindow::onUpdNext(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->can_next()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMWindow::onCmdPrev(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->prev(); return 1; } long GMWindow::onUpdPrev(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->can_prev()) sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL); return 1; } long GMWindow::onCmdTimeSlider(FXObject*,FXSelector,void*ptr){ FXint pos=(FXint)(FXival)ptr; GMPlayerManager::instance()->seek(pos); return 1; } long GMWindow::onCmdVolume(FXObject*,FXSelector,void*ptr){ FXint level = (FXint)(FXival)ptr; GMPlayerManager::instance()->volume(level); update_volume_display(level); return 1; } long GMWindow::onCmdVolumeButton(FXObject*,FXSelector sel,void*ptr){ volumeslider->handle(this,FXSEL(FXSELTYPE(sel),0),ptr); return 1; } long GMWindow::onUpdVolumeButton(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPlayer()->opened()) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMWindow::onCmdRepeatAB(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPlayer()->setRepeatAB(); return 1; } long GMWindow::onUpdRepeatAB(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPlayer()->playing() && GMPlayerManager::instance()->getPlayer()->seekable()) { const FXString state_off = tr("Repeat A-B"); const FXString state_a = tr("Repeat A"); const FXString state_b = tr("Repeat A-B"); sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); switch(GMPlayerManager::instance()->getPlayer()->getRepeatAB()){ case REPEAT_AB_OFF: sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&state_off); break; case REPEAT_AB_A : sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&state_a); break; case REPEAT_AB_B : sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&state_b); break; } } else { sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); } return 1; } long GMWindow::onCmdRepeatOff(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPreferences().play_repeat=REPEAT_OFF; return 1; } long GMWindow::onUpdRepeatOff(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPreferences().play_repeat==REPEAT_OFF) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMWindow::onCmdRepeat(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPreferences().play_repeat=REPEAT_TRACK; return 1; } long GMWindow::onUpdRepeat(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPreferences().play_repeat==REPEAT_TRACK) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMWindow::onCmdRepeatAll(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPreferences().play_repeat=REPEAT_ALL; return 1; } long GMWindow::onUpdRepeatAll(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPreferences().play_repeat==REPEAT_ALL) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMWindow::onCmdShuffle(FXObject*,FXSelector,void*ptr){ GMPlayerManager::instance()->getPreferences().play_shuffle = (FXbool)(FXival)(ptr); return 1; } long GMWindow::onUpdShuffle(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->getPreferences().play_shuffle) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } long GMWindow::onCmdHomePage(FXObject*,FXSelector,void*){ if (!gm_open_browser("http://code.google.com/p/gogglesmm")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit http://code.google.com/p/gogglesmm for the official homepage."); } return 1; } long GMWindow::onCmdReportIssue(FXObject*,FXSelector,void*){ if (!gm_open_browser("http://code.google.com/p/gogglesmm/issues/list")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit http://code.google.com/p/gogglesmm/issues/list to report an issue."); } return 1; } long GMWindow::onCmdJoinLastFM(FXObject*,FXSelector,void*){ if (!gm_open_browser("https://www.last.fm/join/")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit https://www.last.fm/join/"); } return 1; } long GMWindow::onCmdJoinGMMLastFM(FXObject*,FXSelector,void*){ if (!gm_open_browser("http://www.last.fm/group/Goggles+Music+Manager")){ FXMessageBox::error(this,MBOX_OK,tr("Unable to launch webbrowser"),"Goggles Music Manager was unable to launch a webbrowser.\nPlease visit http://www.last.fm/group/Goggles+Music+Manager"); } return 1; } extern const FXchar gmfilepatterns[]; class GMOpenDialog : public FXDialogBox { FXDECLARE(GMOpenDialog) protected: GMTextField * input; protected: GMOpenDialog(){} private: GMOpenDialog(const GMOpenDialog&); GMOpenDialog &operator=(const GMOpenDialog&); public: enum { ID_BROWSE = FXDialogBox::ID_LAST, ID_LAST }; public: long onCmdBrowse(FXObject*,FXSelector,void*); long onCmdAccept(FXObject*,FXSelector,void*); public: GMOpenDialog(FXWindow*); FXString getFilename() const; }; FXDEFMAP(GMOpenDialog) GMOpenDialogMap[]={ FXMAPFUNC(SEL_COMMAND,GMOpenDialog::ID_BROWSE,GMOpenDialog::onCmdBrowse), FXMAPFUNC(SEL_COMMAND,GMOpenDialog::ID_ACCEPT,GMOpenDialog::onCmdAccept) }; FXIMPLEMENT(GMOpenDialog,FXDialogBox,GMOpenDialogMap,ARRAYNUMBER(GMOpenDialogMap)); GMOpenDialog::GMOpenDialog(FXWindow*p) : FXDialogBox(p,fxtr("Play File or Stream"),DECOR_TITLE|DECOR_BORDER,0,0,0,0,4,4,4,4) { FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0); new GMButton(closebox,tr("&Play"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,tr("&Cancel"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(this,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXVerticalFrame * vframe = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y); new FXLabel(vframe,tr("Please specify a file or url to play:"),NULL); FXHorizontalFrame *inputframe=new FXHorizontalFrame(vframe,LAYOUT_FILL_X,0,0,0,0,0,0,0,0); input = new GMTextField(inputframe,40,NULL,0,TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_CENTER_Y); new GMButton(inputframe,tr("…"),NULL,this,ID_BROWSE); input->setText(getApp()->reg().readStringEntry("GMOpenDialog","url",NULL)); } long GMOpenDialog::onCmdBrowse(FXObject*,FXSelector,void*){ GMFileDialog filedialog(this,tr("Select File")); if (!input->getText().empty()) filedialog.setFilename(input->getText()); filedialog.setPatternList(gmfilepatterns); if (filedialog.execute()) input->setText(filedialog.getFilename()); return 1; } long GMOpenDialog::onCmdAccept(FXObject*sender,FXSelector sel,void*ptr){ getApp()->reg().writeStringEntry("GMOpenDialog","url",input->getText().text()); return FXDialogBox::onCmdAccept(sender,sel,ptr); } FXString GMOpenDialog::getFilename() const { return input->getText(); } long GMWindow::onCmdOpen(FXObject*,FXSelector,void*){ GMOpenDialog dialog(this); if (dialog.execute()) { FXString filename = dialog.getFilename(); GMPlayerManager::instance()->open(filename); } return 1; } long GMWindow::onCmdSleepTimer(FXObject*,FXSelector,void*ptr){ if (((FXint)(FXival)ptr)==1) { FXDialogBox dialog(this,tr("Sleep Timer"),DECOR_TITLE|DECOR_BORDER,0,0,0,0,0,0,0,0,0,0); create_dialog_header(&dialog,tr("Setup sleep timer"),tr("Stop playback within a certain time"),NULL); FXHorizontalFrame *closebox=new FXHorizontalFrame(&dialog,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0); new GMButton(closebox,tr("&Start Timer"),NULL,&dialog,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox,tr("&Cancel"),NULL,&dialog,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new FXSeparator(&dialog,SEPARATOR_GROOVE|LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM); FXHorizontalFrame * main = new FXHorizontalFrame(&dialog,LAYOUT_FILL_X,0,0,0,0,40,40,10,10); new FXLabel(main,tr("Sleep in"),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y); GMSpinner* hours = new GMSpinner(main,2,NULL,0,FRAME_SUNKEN|FRAME_THICK); new FXLabel(main,tr("hours and"),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y); GMSpinner* minutes = new GMSpinner(main,2,NULL,0,FRAME_SUNKEN|FRAME_THICK); new FXLabel(main,tr("minutes."),NULL,LABEL_NORMAL|LAYOUT_CENTER_Y); minutes->setRange(0,59); hours->setRange(0,24); minutes->setValue(FXCLAMP(0,getApp()->reg().readIntEntry("player","sleeptimer-minutes",0),59)); hours->setValue(FXCLAMP(0,getApp()->reg().readIntEntry("player","sleeptimer-hours",2),24)); if (dialog.execute()) { GMPlayerManager::instance()->setSleepTimer(TIME_HOUR(hours->getValue())+TIME_MIN(minutes->getValue())); getApp()->reg().writeIntEntry("player","sleeptimer-minutes",minutes->getValue()); getApp()->reg().writeIntEntry("player","sleeptimer-hours",hours->getValue()); } } else { GMPlayerManager::instance()->setSleepTimer(0); } return 1; } long GMWindow::onUpdSleepTimer(FXObject*sender,FXSelector,void*){ if (GMPlayerManager::instance()->hasSleepTimer()) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } extern const char *albumartfiles[]; void GMWindow::loadCover(const FXString & filename) { FXIconSource src(getApp()); FXImage * cover=NULL; FXint coverdisplaysize; FXString dirname=filename; const FXint smallcoversize=64; /// Whether to scale the image when loading or not if (coverview_gl) coverdisplaysize=0; else coverdisplaysize=FXCLAMP(64,GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size,500); /// Check if we've already loaded it. if (filename==coverfile) { return; } /// If empty skip cover searching if (!filename.empty()) { cover = GMCover::toImage(GMCover::fromTag(filename,coverdisplaysize)); if (cover==NULL) { dirname = FXPath::directory(filename); if (!dirname.empty()) { if (dirname==coverfile) return; cover= GMCover::toImage(GMCover::fromPath(dirname,coverdisplaysize)); } } } /// Delete current cover if (remote) remote->updateCover(NULL); if (cover_small) { FXImage * img = cover_small.release(); delete img; } if (coverview_x11) { if (coverview_x11->getImage()){ delete coverview_x11->getImage(); coverview_x11->setImage(NULL); } } /// Set new cover to coverview if (coverview_gl) coverview_gl->setImage(cover); else coverview_x11->setImage(cover); if (cover) { coverfile = dirname; /// Retrieve Image Data FXColor * imagedata = cover->getData(); /// Disown image data FXImageOwner::clear(cover); /// Make sure to create cover for x11 if (coverview_x11) cover->create(); /// Make small cover the owner of the data cover_small = new FXImage(getApp(),imagedata,IMAGE_SHMI|IMAGE_SHMP|IMAGE_KEEP|IMAGE_OWNED,cover->getWidth(),cover->getHeight()); if (cover_small->getWidth()>smallcoversize || cover_small->getHeight()>smallcoversize) { if (cover_small->getWidth()>cover_small->getHeight()) cover_small->scale(smallcoversize,(smallcoversize*cover_small->getHeight())/cover_small->getWidth(),1); else cover_small->scale((smallcoversize*cover_small->getWidth())/cover_small->getHeight(),smallcoversize,1); } /// delete the cover for gl. if (coverview_gl) delete cover; cover_small->create(); if (remote) remote->updateCover(cover_small); if (!coverframe->shown()) { coverframe->show(); coverframe->recalc(); } } else { coverfile = FXString::null; if (coverframe->shown()) { coverframe->hide(); coverframe->recalc(); } } } void GMWindow::create_dialog_header(FXDialogBox * dialog,const FXString & title,const FXString & subtitle,FXIcon * icon) { FXHorizontalFrame * header = new FXHorizontalFrame(dialog,LAYOUT_FILL_X,0,0,0,0,0,0,0,0,0,0); header->setBackColor(getApp()->getBackColor()); FXLabel * label = new FXLabel(header,FXString::null,icon,LABEL_NORMAL|LAYOUT_CENTER_Y,0,0,0,0,10,0,0,0); label->setBackColor(getApp()->getBackColor()); FXVerticalFrame * frame = new FXVerticalFrame(header,LAYOUT_FILL_X,0,0,0,0,0,0,0,0,0,0); label = new FXLabel(frame,title,NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10,10,10,0); label->setBackColor(getApp()->getBackColor()); label->setFont(font_thick); label = new FXLabel(frame,subtitle,NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10+30,10,0,10); label->setBackColor(getApp()->getBackColor()); new FXSeparator(dialog,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_TOP); } void GMWindow::updateCoverView() { if (GMPlayerManager::instance()->getPreferences().gui_show_opengl_coverview && gm_has_opengl() ) { if (coverview_x11) { loadCover(FXString::null); delete coverview_x11; coverview_x11=NULL; } if (!coverview_gl) { #if FOXVERSION < FXVERSION(1,7,15) glvisual = new FXGLVisual(getApp(),VISUAL_DOUBLEBUFFER); #else glvisual = new FXGLVisual(getApp(),VISUAL_DOUBLE_BUFFER); #endif coverview_gl = new GMImageView(coverframe,glvisual,LAYOUT_FILL_X|LAYOUT_FILL_Y); coverview_gl->setTarget(this); coverview_gl->setSelector(ID_COVERVIEW); coverview_gl->enable(); if (coverframe->id()) coverview_gl->create(); } } else { if (coverview_gl) { loadCover(FXString::null); delete coverview_gl; coverview_gl=NULL; delete glvisual; glvisual=NULL; } if (!coverview_x11) { coverview_x11 = new FXImageFrame(coverframe,NULL,FRAME_NONE|JUSTIFY_CENTER_X|JUSTIFY_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0); coverview_x11->setBackColor(getApp()->getBackColor()); coverview_x11->setTarget(this); coverview_x11->setSelector(ID_COVERVIEW); coverview_x11->enable(); if (coverframe->id()) coverview_x11->create(); } } } long GMWindow::onCmdCoverView(FXObject*,FXSelector,void*ptr){ FXEvent * event = reinterpret_cast(ptr); if (!event->moved) { GMMenuPane pane(this); if (coverview_x11) { if (gm_has_opengl()) { new GMMenuCheck(&pane,"Use OpenGL viewer",this,ID_CHANGE_COVERVIEW); new FXMenuSeparator(&pane); } new GMMenuRadio(&pane,"Small Cover",this,ID_COVERSIZE_SMALL); new GMMenuRadio(&pane,"Medium Cover",this,ID_COVERSIZE_MEDIUM); new GMMenuRadio(&pane,"Large Cover",this,ID_COVERSIZE_LARGE); new GMMenuRadio(&pane,"Extra Large Cover",this,ID_COVERSIZE_EXTRALARGE); } else { new GMMenuCheck(&pane,"Use X11 viewer",this,ID_CHANGE_COVERVIEW); } gm_set_window_cursor(&pane,getApp()->getDefaultCursor(DEF_ARROW_CURSOR)); pane.create(); ewmh_change_window_type(&pane,WINDOWTYPE_POPUP_MENU); pane.popup(NULL,event->root_x+3,event->root_y+3); getApp()->runPopup(&pane); return 1; } return 0; } long GMWindow::onCmdChangeCoverView(FXObject*,FXSelector,void*){ GMPlayerManager::instance()->getPreferences().gui_show_opengl_coverview=!GMPlayerManager::instance()->getPreferences().gui_show_opengl_coverview; updateCoverView(); if (GMPlayerManager::instance()->playing()) GMPlayerManager::instance()->update_cover_display(); return 1; } long GMWindow::onCmdCoverSize(FXObject*,FXSelector sel,void*){ switch(FXSELID(sel)){ case ID_COVERSIZE_SMALL : GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size=128; break; case ID_COVERSIZE_MEDIUM : GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size=256; break; case ID_COVERSIZE_LARGE : GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size=384; break; case ID_COVERSIZE_EXTRALARGE : GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size=512; break; } loadCover(FXString::null); if (GMPlayerManager::instance()->playing()) GMPlayerManager::instance()->update_cover_display(); return 1; } long GMWindow::onUpdCoverSize(FXObject*sender,FXSelector sel,void*){ FXbool check=false; switch(FXSELID(sel)){ case ID_COVERSIZE_SMALL : check = (GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size<=128); break; case ID_COVERSIZE_MEDIUM : check = ((GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size>128) && (GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size<384)); break; case ID_COVERSIZE_LARGE : check = ((GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size>=384) && (GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size<512)); break; case ID_COVERSIZE_EXTRALARGE : check = (GMPlayerManager::instance()->getPreferences().gui_coverdisplay_size>=512); break; } if (check) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } #if FOXVERSION > FXVERSION(1,7,21) long GMWindow::onCmdShowSources(FXObject*,FXSelector,void*){ if (mainsplitter->getExpanded()==HIDESOURCES) { if (!coverfile.empty()) mainsplitter->setExpanded(SHOWSOURCES_COVER); else mainsplitter->setExpanded(SHOWSOURCES); } else mainsplitter->setExpanded(HIDESOURCES); return 1; } long GMWindow::onUpdShowSources(FXObject*sender,FXSelector,void*){ FXuint exp = mainsplitter->getExpanded(); if (exp==SHOWSOURCES || exp==SHOWSOURCES_COVER) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } #endif gogglesmm-0.12.7/src/fxext.h0000644000175000001440000003551511550640330014411 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef FXEXT_H #define FXEXT_H enum { WINDOWTYPE_NORMAL, WINDOWTYPE_DIALOG, WINDOWTYPE_COMBO, WINDOWTYPE_POPUP_MENU, WINDOWTYPE_DROPDOWN_MENU, WINDOWTYPE_TOOLTIP, }; extern void ewmh_change_window_type(const FXWindow *,FXuint); extern void ewmh_set_window_icon(const FXWindow *,FXImage *); extern void ewmh_activate_window(const FXWindow*); extern void fix_wm_properties(const FXWindow*); class FXIconThreshold : public FXIcon { public: #if FOXVERSION >= FXVERSION(1,7,22) static void set(FXIcon*ic) { FXIconThreshold * ih = (FXIconThreshold*) ic; ih->setThresholdValue(ih->guessthresh()); } #else static void set(FXIcon*) {} #endif }; /// We need this to allow reading ini files with long lines. class GMSettings : public FXSettings { FXDECLARE(GMSettings) #if FOXVERSION < FXVERSION(1,7,0) public: FXbool parseFile(const FXString & filename,FXbool mark); #endif }; class GMListBox : public FXListBox { FXDECLARE(GMListBox) protected: GMListBox(); private: GMListBox(const GMListBox&); GMListBox& operator=(const GMListBox&); public: GMListBox(FXComposite*,FXObject*tgt=NULL,FXSelector sel=0,FXuint opts=FRAME_SUNKEN|FRAME_THICK|LISTBOX_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); virtual void create(); }; class GMComboBox : public FXComboBox { FXDECLARE(GMComboBox) protected: GMComboBox(); private: GMComboBox(const GMComboBox&); GMComboBox& operator=(const GMComboBox&); public: GMComboBox(FXComposite *p,FXint cols,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=COMBOBOX_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); virtual void create(); }; class GMScrollArea : public FXScrollArea { FXDECLARE(GMScrollArea) protected: GMScrollArea(){} private: GMScrollArea(const GMScrollArea&); GMScrollArea& operator=(const GMScrollArea&); public: static void replaceScrollbars(FXScrollArea*); }; class GMTreeListBox : public FXTreeListBox { FXDECLARE(GMTreeListBox) protected: GMTreeListBox(){} private: GMTreeListBox(const GMTreeListBox&); GMTreeListBox& operator=(const GMTreeListBox&); public: static void replace(FXTreeListBox*); }; class GMTabBook : public FXTabBook { FXDECLARE(GMTabBook) protected: GMTabBook(){} private: GMTabBook(const GMTabBook&); GMTabBook& operator=(const GMTabBook&); public: GMTabBook(FXComposite* p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=TABBOOK_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_SPACING,FXint pr=DEFAULT_SPACING,FXint pt=DEFAULT_SPACING,FXint pb=DEFAULT_SPACING); virtual void setCurrent(FXint panel,FXbool notify=false); }; class FXAPI GMTabItem : public FXTabItem { FXDECLARE(GMTabItem) protected: GMTabItem(){} private: GMTabItem(const GMTabItem&); GMTabItem& operator=(const GMTabItem&); public: long onPaint(FXObject*,FXSelector,void*); public: /// Construct a tab item GMTabItem(FXTabBar* p,const FXString& text,FXIcon* ic=0,FXuint opts=TAB_TOP_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); // virtual void raise(); }; class GMHeaderItem : public FXHeaderItem { FXDECLARE(GMHeaderItem) friend class GMHeader; protected: GMHeaderItem(){} public: /// Construct new item with given text, icon, size, and user-data GMHeaderItem(const FXString& text,FXIcon* ic=NULL,FXint s=0,void* ptr=NULL): FXHeaderItem(text,ic,s,ptr) {} }; class FXAPI GMHeader : public FXHeader { FXDECLARE(GMHeader) protected: GMHeader(); private: GMHeader(const GMHeader&); GMHeader &operator=(const GMHeader&); public: long onPaint(FXObject*,FXSelector,void*); public: GMHeader(FXComposite* p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=HEADER_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMHeaderButton : public FXButton { FXDECLARE(GMHeaderButton) protected: FXuint arrowstate; protected: GMHeaderButton(); private: GMHeaderButton(const GMHeaderButton&); GMHeaderButton& operator=(const GMHeaderButton&); public: long onPaint(FXObject*,FXSelector,void*); public: /// Construct button with text and icon GMHeaderButton(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=BUTTON_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); void setArrowState(FXuint s); FXuint getArrowState() const; }; class GMMenuCommand : public FXMenuCommand { FXDECLARE(GMMenuCommand) protected: GMMenuCommand(){} private: GMMenuCommand(const GMMenuCommand&); GMMenuCommand& operator=(const GMMenuCommand&); public: GMMenuCommand(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0); }; class GMMenuCheck : public FXMenuCheck { FXDECLARE(GMMenuCheck) protected: GMMenuCheck(){} private: GMMenuCheck(const GMMenuCheck&); GMMenuCheck& operator=(const GMMenuCheck&); public: GMMenuCheck(FXComposite* p,const FXString& text,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0); }; class GMMenuRadio : public FXMenuRadio { FXDECLARE(GMMenuRadio) protected: GMMenuRadio(){} private: GMMenuRadio(const GMMenuRadio&); GMMenuRadio& operator=(const GMMenuRadio&); public: GMMenuRadio(FXComposite* p,const FXString& text,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0); }; class GMMenuCascade : public FXMenuCascade { FXDECLARE(GMMenuCascade) protected: GMMenuCascade(){} private: GMMenuCascade(const GMMenuCascade&); GMMenuCascade& operator=(const GMMenuCascade&); public: GMMenuCascade(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXPopup* pup=NULL,FXuint opts=0); }; class GMMenuTitle : public FXMenuTitle { FXDECLARE(GMMenuTitle) protected: GMMenuTitle(){} private: GMMenuTitle(const GMMenuTitle&); GMMenuTitle& operator=(const GMMenuTitle&); public: long onPaint(FXObject*,FXSelector,void*); long onCmdPost(FXObject*,FXSelector,void*); public: GMMenuTitle(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXPopup* pup=NULL,FXuint opts=0); }; /// Popup menu pane class GMMenuPane : public FXMenuPane { FXDECLARE(GMMenuPane) protected: GMMenuPane(){} private: GMMenuPane(const GMMenuPane&); GMMenuPane &operator=(const GMMenuPane&); public: /// Construct menu pane GMMenuPane(FXWindow* owner,FXuint opts=0); }; class GMButton : public FXButton { FXDECLARE(GMButton) protected: GMButton(); private: GMButton(const GMButton&); GMButton& operator=(const GMButton&); public: long onPaint(FXObject*,FXSelector,void*); public: GMButton(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=BUTTON_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMToggleButton : public FXToggleButton { FXDECLARE(GMToggleButton) protected: GMToggleButton(); private: GMToggleButton(const GMToggleButton&); GMToggleButton& operator=(const GMToggleButton&); public: long onPaint(FXObject*,FXSelector,void*); public: GMToggleButton(FXComposite* p,const FXString& text1,const FXString& text2,FXIcon* icon1=NULL,FXIcon* icon2=NULL,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=TOGGLEBUTTON_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMRadioButton : public FXRadioButton { FXDECLARE(GMRadioButton) protected: GMRadioButton(); private: GMRadioButton(const GMRadioButton&); GMRadioButton& operator=(const GMRadioButton&); public: GMRadioButton(FXComposite* p,const FXString& text,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=RADIOBUTTON_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMCheckButton : public FXCheckButton { FXDECLARE(GMCheckButton) protected: GMCheckButton(); private: GMCheckButton(const GMCheckButton&); GMCheckButton& operator=(const GMCheckButton&); public: long onPaint(FXObject*,FXSelector,void*); public: GMCheckButton(FXComposite* p,const FXString& text,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=CHECKBUTTON_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMMenuButton : public FXMenuButton { FXDECLARE(GMMenuButton) protected: GMMenuButton(); private: GMMenuButton(const GMMenuButton&); GMMenuButton& operator=(const GMMenuButton&); public: long onPaint(FXObject*,FXSelector,void*); public: GMMenuButton(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXPopup* pup=NULL,FXuint opts=JUSTIFY_NORMAL|ICON_BEFORE_TEXT|MENUBUTTON_DOWN,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); virtual FXint getDefaultWidth(); virtual FXint getDefaultHeight(); }; class GMTextField : public FXTextField { FXDECLARE(GMTextField) protected: GMTextField(){} private: GMTextField(const GMTextField&); GMTextField& operator=(const GMTextField&); public: long onLeftBtnPress(FXObject*,FXSelector,void*); public: GMTextField(FXComposite* p,FXint ncols,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=TEXTFIELD_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); FXbool extendWordSelection(FXint p,FXbool notify=false); }; class GMScrollFrame : public FXVerticalFrame { FXDECLARE(GMScrollFrame) protected: GMScrollFrame(); private: GMScrollFrame(const GMScrollFrame&); GMScrollFrame& operator=(const GMScrollFrame&); public: GMScrollFrame(FXComposite*p); }; class GMCoverFrame : public FXVerticalFrame { FXDECLARE(GMCoverFrame) protected: GMCoverFrame(); private: GMCoverFrame(const GMCoverFrame&); GMCoverFrame& operator=(const GMCoverFrame&); public: GMCoverFrame(FXComposite*p); }; class GMScrollHFrame : public FXHorizontalFrame { FXDECLARE(GMScrollHFrame) protected: GMScrollHFrame(); private: GMScrollHFrame(const GMScrollHFrame&); GMScrollHFrame& operator=(const GMScrollHFrame&); public: GMScrollHFrame(FXComposite*p); }; class GMTabFrame : public FXVerticalFrame { FXDECLARE(GMTabFrame) protected: GMTabFrame(); private: GMTabFrame(const GMTabFrame&); GMTabFrame& operator=(const GMTabFrame&); public: GMTabFrame(FXComposite*p); }; class GMImageFrame : public FXImageFrame { FXDECLARE(GMImageFrame) protected: GMImageFrame(); private: GMImageFrame(const GMImageFrame&); GMImageFrame& operator=(const GMImageFrame&); public: GMImageFrame(FXComposite*p,FXImage *img,FXuint opts=FRAME_SUNKEN|FRAME_THICK,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=0,FXint pr=0,FXint pt=0,FXint pb=0); }; class GMScrollBar : public FXScrollBar { FXDECLARE(GMScrollBar) protected: GMScrollBar(); void drawThumb(FXDCWindow& dc,FXint x,FXint y,FXint w,FXint h); private: GMScrollBar(const GMScrollBar&); GMScrollBar &operator=(const GMScrollBar&); public: long onPaint(FXObject*,FXSelector,void*); public: /// Construct scroll bar GMScrollBar(FXComposite* p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=SCROLLBAR_VERTICAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0); }; class GMScrollCorner : public FXScrollCorner { FXDECLARE(GMScrollCorner) protected: FXColor shadowColor; protected: GMScrollCorner() {} private: GMScrollCorner(const GMScrollCorner&); GMScrollCorner &operator=(const GMScrollCorner&); public: long onPaint(FXObject*,FXSelector,void*); public: GMScrollCorner(FXComposite* p); }; class GMSpinner : public FXSpinner { FXDECLARE(GMSpinner) protected: GMSpinner(){} private: GMSpinner(const GMSpinner&); GMSpinner& operator=(const GMSpinner&); public: GMSpinner(FXComposite* p,FXint ncols,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=SPIN_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMProgressBar : public FXProgressBar { FXDECLARE(GMProgressBar) protected: GMProgressBar(); private: GMProgressBar(const GMProgressBar&); GMProgressBar &operator=(const GMProgressBar&); public: /// Construct progress bar GMProgressBar(FXComposite* p,FXObject* target=NULL,FXSelector sel=0,FXuint opts=PROGRESSBAR_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class GMTrackProgressBar : public FXProgressBar { FXDECLARE(GMTrackProgressBar) protected: GMTrackProgressBar(); private: GMTrackProgressBar(const GMTrackProgressBar&); GMTrackProgressBar &operator=(const GMTrackProgressBar&); public: long onMotion(FXObject*,FXSelector,void*); long onLeftBtnPress(FXObject*,FXSelector,void*); long onLeftBtnRelease(FXObject*,FXSelector,void*); public: /// Construct progress bar GMTrackProgressBar(FXComposite* p,FXObject* target=NULL,FXSelector sel=0,FXuint opts=PROGRESSBAR_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD); }; class FXImageOwner : public FXImage { public: FXImageOwner(); static void clear(FXImage * img) { FXImageOwner* owner = (FXImageOwner*) img; owner->options&=~IMAGE_OWNED; } }; #endif gogglesmm-0.12.7/src/GMPlayerManager.h0000644000175000001440000001546011667300652016234 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMPLAYERMANAGER_H #define GMPLAYERMANAGER_H #ifndef GMPREFERENCES_H #include "GMPreferences.h" #endif #ifndef GMSOURCE_H #include "GMSource.h" #endif class GMPlayList; class GMTrackList; class GMTrackView; class GMPlayer; class GMWindow; class GMRemote; class GMTrackDatabase; class GMPlayer; class GMPlayList; class GMSource; class GMSourceView; class GMFetch; class GMEQDialog; #ifdef HAVE_DBUS class GMDBus; class GMNotifyDaemon; class GMMediaPlayerService; class GMSettingsDaemon; #endif class GMAudioScrobbler; class GMTrayIcon; class GMDatabaseSource; class GMPlayerManager : public FXObject { FXDECLARE(GMPlayerManager) private: static GMPlayerManager * myself; protected: GMPreferences preferences; GMSourceList sources; FXString fifofilename; FXFile fifo; #if FOXVERSION < FXVERSION(1,7,0) FXuint count_track_remaining; #else FXlong count_track_remaining; #endif protected: #ifdef HAVE_DBUS GMDBus * sessionbus; GMDBus * systembus; GMNotifyDaemon * notifydaemon; GMMediaPlayerService * mpris; GMSettingsDaemon * gsd; #endif FXApp * application; GMWindow * mainwindow; GMPlayer * player; GMTrayIcon * trayicon; GMAudioScrobbler * lastfm; GMTrackDatabase * database; protected: GMSource * source; GMTrack trackinfo; FXbool trackinfoset; protected: FXbool hasSourceWithKey(const char * key) const; void cleanSourceSettings(); public: static GMPlayerManager * instance(); public: enum { ID_UPDATE_TRACK_DISPLAY = 1, ID_HANDLE_EVENTS, ID_COUNT_TRACK, ID_SLEEP_TIMER, ID_SCAN_AUDIOCD, ID_DDE_MESSAGE, ID_DOWNLOAD_COMPLETE, ID_PLAY_NOTIFY, ID_REMOTE, ID_WINDOW, ID_EQUALIZER, ID_SCROBBLER, ID_PLAYER_ERROR, ID_GNOME_SETTINGS_DAEMON, ID_SHOW_MANAGER, ID_CHILD }; public: long onUpdTrackDisplay(FXObject*,FXSelector,void*); long onUpdEvents(FXObject*,FXSelector,void*); long onCmdCountTrack(FXObject*,FXSelector,void*); long onCmdSleepTimer(FXObject*,FXSelector,void*); long onDDEMessage(FXObject*,FXSelector,void*); long onCmdDownloadComplete(FXObject*,FXSelector,void*); long onCmdCloseWindow(FXObject*,FXSelector,void*); long onCmdShowManager(FXObject*,FXSelector,void*); long onPlayNotify(FXObject*,FXSelector,void*); long onCmdChild(FXObject*,FXSelector,void*); long onCmdEqualizer(FXObject*,FXSelector,void*); long onScrobblerError(FXObject*,FXSelector,void*); long onScrobblerOpen(FXObject*,FXSelector,void*); long onPlayerError(FXObject*,FXSelector,void*); #ifdef HAVE_DBUS long onCmdSettingsDaemon(FXObject*,FXSelector,void*); #endif protected: FXint init_fifo(int & argc,char**argv); FXbool init_database(GMTrackDatabase *&,const FXString & filename); FXbool init_sources(); void init_window(FXbool wizard); public: GMPlayerManager(); void getTrackInformation(GMTrack & t) const { t=trackinfo; } FXint run(int & argc,char**argv); /// Change Source void setSource(FXuint source); void update_tray_icon(); FXint getNumSources() const { return sources.no(); } GMSource * getSource(FXint i) const { return sources[i]; } void removeSource(GMSource * src); void insertSource(GMSource * src) { sources.append(src); } void removePlayListSources(); GMSource * getSource() const { return source; } GMDatabaseSource * getDatabaseSource() const; GMWindow * getMainWindow() const { return mainwindow; } GMTrackView * getTrackView() const; GMSourceView * getSourceView() const; GMPlayer * getPlayer() const { return player; } GMPreferences & getPreferences() { return preferences; } GMAudioScrobbler * getAudioScrobbler() { return lastfm; } GMTrayIcon * getTrayIcon() { return trayicon; } #ifdef HAVE_DBUS FXbool hasSessionBus() const { return (sessionbus!=NULL) ; } #endif void exit(); void cmd_play(); void cmd_playpause(); void cmd_pause(); void cmd_stop(); void cmd_next(); void cmd_prev(); void cmd_toggle_shown(); FXbool can_play() const; FXbool can_pause() const; FXbool can_unpause() const; FXbool can_next() const; FXbool can_prev() const; FXbool can_stop() const; void play(); FXbool play(const FXString & mrl); FXbool play(const FXStringList & mrl); void download(const FXString & mrl); void open(const FXString & mrl); void pause(); void unpause(); void stop(FXbool closedevice=false); void next(); void prev(); void volume(FXint l); FXint volume() const; void seek(FXint pos); FXbool playlist_empty(); void notify_playback_finished(); void reset_track_display(); void update_track_display(FXbool notify=true); void update_replay_gain(); FXint current_position() const; FXbool playing() const; FXbool audio_device_opened() const; FXint get_prev() const; FXint get_next() const; /// Set Sleep Timer - 0 turns the timer off #if FOXVERSION < FXVERSION(1,7,0) void setSleepTimer(FXuint ms); #else void setSleepTimer(FXlong ns); #endif FXbool hasSleepTimer(); void handle_async_events(); void show_message(const FXchar * title,const FXchar * msg); void setStatus(const FXString & msg); void register_global_hotkeys(); FXbool handle_global_hotkeys(FXuint code); void update_cover_display(); FXint createPlaylist(const FXString & name); void display_track_notification(); ~GMPlayerManager(); }; #endif gogglesmm-0.12.7/src/GMImportDialog.cpp0000644000175000001440000007721312005633732016431 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include "gmdefs.h" #include #include #include "icons.h" #include "GMApp.h" #include "GMIconTheme.h" #include "GMPlayerManager.h" #include "GMWindow.h" #include "GMImportDialog.h" extern const FXchar gmfilepatterns[]="All Music (*.mp3,*.ogg,*.oga,*.flac,*.mpc,*.wav" #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) ",*.aac,*.m4a,*.m4p,*.mp4,*.m4b" #endif #if defined(TAGLIB_WITH_ASF) && (TAGLIB_WITH_ASF==1) ",*.wma,*.asf" #endif ")\nFree Lossless Audio Codec (*.flac)\nWaveform Audio File Format (*.wav)\n" "MPEG-1 Audio Layer 3 (*.mp3)\n" #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) "MPEG-4 Part 14 (*.mp4,*.m4a,*.m4p,*.aac,*.m4b)\n" #endif "Musepack (*.mpc)\n" "Ogg Vorbis (*.ogg)\n" "Ogg Audio (*.oga)\n" #if defined(TAGLIB_WITH_ASF) && (TAGLIB_WITH_ASF==1) "Window Media (*.wma,*,asf)\n" #endif "All Files (*.*)"; const FXchar playlist_patterns[]="All Playlists (*.xspf,*.pls,*.m3u)\nXML Shareable Playlist (*.xspf)\nPLS (*.pls)\nM3U (*.m3u)"; class GMDirSelector : public FXDirSelector { FXDECLARE(GMDirSelector) protected: FXFileDict * filedict; FXSettings * fileassoc; protected: FXIconPtr icon_folder; FXIconPtr icon_folderopen; protected: GMDirSelector(){} private: GMDirSelector(const GMDirSelector&); GMDirSelector &operator=(const GMDirSelector&); public: GMDirSelector(FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); ~GMDirSelector(); void initFileDict(); }; FXIMPLEMENT(GMDirSelector,FXDirSelector,NULL,0); GMDirSelector::GMDirSelector(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h):FXDirSelector(p,tgt,sel,opts,x,y,w,h) { fileassoc=new FXSettings(); filedict=new FXFileDict(getApp(),fileassoc); initFileDict(); delete accept->getParent(); delete dirbox->getParent(); delete dirname->getParent(); // FXHorizontalFrame *buttons=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH); // accept=new FXButton(buttons,tr("&OK"),NULL,NULL,0,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); // cancel=new FXButton(buttons,tr("&Cancel"),NULL,NULL,0,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0,20,20); FXHorizontalFrame *field=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); new FXLabel(field,tr("&Directory:"),NULL,JUSTIFY_LEFT|LAYOUT_CENTER_Y); dirname=new GMTextField(field,25,this,ID_DIRNAME,LAYOUT_FILL_X|LAYOUT_CENTER_Y|FRAME_SUNKEN|FRAME_THICK); GMScrollFrame *frame=new GMScrollFrame(this); dirbox=new FXDirList(frame,this,ID_DIRLIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_BROWSESELECT); GMScrollArea::replaceScrollbars(dirbox); ((FXVerticalFrame*)dirbox->getParent())->setFrameStyle(FRAME_LINE); #if FOXVERSION >= FXVERSION(1,7,11) dirbox->setAssociations(filedict,false); #else FXFileDict * old = dirbox->getAssociations(); dirbox->setAssociations(filedict); delete old; #endif } GMDirSelector::~GMDirSelector(){ delete fileassoc; #if FOXVERSION >= FXVERSION(1,7,11) delete filedict; #endif } class GMFileSelector : public FXFileSelector { FXDECLARE(GMFileSelector) protected: FXFileDict * filedict; FXSettings * fileassoc; protected: FXIconPtr icon_file_small; FXIconPtr icon_file_big; FXIconPtr icon_audio_small; FXIconPtr icon_audio_big; FXIconPtr icon_folder_small; FXIconPtr icon_folder_big; protected: GMFileSelector(){} private: GMFileSelector(const GMFileSelector&); GMFileSelector &operator=(const GMFileSelector&); public: GMFileSelector(FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); ~GMFileSelector(); void initFileDict(); void hideButtons(); void getSelectedFiles(FXStringList & files); FXMatrix * optionFrame() const { return entryblock; } }; FXIMPLEMENT(GMFileSelector,FXFileSelector,NULL,0); GMFileSelector::GMFileSelector(FXComposite *p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h):FXFileSelector(p,tgt,sel,opts,x,y,w,h) { FXWindow * window=NULL; while((window=getFirst())!=NULL) delete window; delete bookmarkmenu; bookmarkmenu=NULL; FXAccelTable *table=getShell()->getAccelTable(); navbuttons=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0, 0,0); entryblock=new FXMatrix(this,3,MATRIX_BY_COLUMNS|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); new FXLabel(entryblock,tr("&File Name:"),NULL,JUSTIFY_LEFT|LAYOUT_CENTER_Y); filename=new GMTextField(entryblock,25,this,ID_ACCEPT,TEXTFIELD_ENTER_ONLY|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y); new GMButton(entryblock,tr("&OK"),NULL,this,ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X,0,0,0,0,20,20); accept=new FXButton(navbuttons,FXString::null,NULL,NULL,0,LAYOUT_FIX_X|LAYOUT_FIX_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,0,0,0,0, 0,0,0,0); new FXLabel(entryblock,tr("File F&ilter:"),NULL,JUSTIFY_LEFT|LAYOUT_CENTER_Y); FXHorizontalFrame *filterframe=new FXHorizontalFrame(entryblock,LAYOUT_FILL_COLUMN|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0); filefilter=new GMComboBox(filterframe,10,this,ID_FILEFILTER,COMBOBOX_STATIC|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y); filefilter->setNumVisible(4); readonly=new GMCheckButton(filterframe,tr("Read Only"),NULL,0,ICON_BEFORE_TEXT|JUSTIFY_LEFT|LAYOUT_CENTER_Y); cancel=new GMButton(entryblock,tr("&Cancel"),NULL,NULL,0,BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X,0,0,0,0,20,20); fileboxframe=new GMScrollHFrame(this); filebox=new FXFileList(fileboxframe,this,ID_FILELIST,ICONLIST_MINI_ICONS|ICONLIST_BROWSESELECT|ICONLIST_AUTOSIZE|LAYOUT_FILL_X|LAYOUT_FILL_Y); GMScrollArea::replaceScrollbars(filebox); new FXLabel(navbuttons,tr("Directory:"),NULL,LAYOUT_CENTER_Y); dirbox=new FXDirBox(navbuttons,this,ID_DIRTREE,DIRBOX_NO_OWN_ASSOC|FRAME_LINE|LAYOUT_FILL_X|LAYOUT_CENTER_Y,0,0,0,0,1,1,1,1); dirbox->setNumVisible(5); dirbox->setAssociations(filebox->getAssociations()); GMTreeListBox::replace(dirbox); bookmarkmenu=new GMMenuPane(this,POPUP_SHRINKWRAP); new GMMenuCommand(bookmarkmenu,tr("&Set bookmark\t\tBookmark current directory."),markicon,this,ID_BOOKMARK); new GMMenuCommand(bookmarkmenu,tr("&Clear bookmarks\t\tClear bookmarks."),clearicon,&bookmarks,FXRecentFiles::ID_CLEAR); FXMenuSeparator* sep1=new FXMenuSeparator(bookmarkmenu); sep1->setTarget(&bookmarks); sep1->setSelector(FXRecentFiles::ID_ANYFILES); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_1); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_2); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_3); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_4); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_5); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_6); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_7); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_8); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_9); new GMMenuCommand(bookmarkmenu,FXString::null,NULL,&bookmarks,FXRecentFiles::ID_FILE_10); new FXFrame(navbuttons,LAYOUT_FIX_WIDTH,0,0,4,1); new GMButton(navbuttons,tr("\tGo up one directory\tMove up to higher directory."),updiricon,this,ID_DIRECTORY_UP,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMButton(navbuttons,tr("\tGo to home directory\tBack to home directory."),homeicon,this,ID_HOME,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMButton(navbuttons,tr("\tGo to work directory\tBack to working directory."),workicon,this,ID_WORK,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); GMMenuButton *bookmenu=new GMMenuButton(navbuttons,tr("\tBookmarks\tVisit bookmarked directories."),markicon,bookmarkmenu,MENUBUTTON_NOARROWS|MENUBUTTON_ATTACH_LEFT|MENUBUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); bookmenu->setTarget(this); bookmenu->setSelector(ID_BOOKMENU); new GMButton(navbuttons,tr("\tCreate new directory\tCreate new directory."),newicon,this,ID_NEW,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMButton(navbuttons,tr("\tShow list\tDisplay directory with small icons."),listicon,filebox,FXFileList::ID_SHOW_MINI_ICONS,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMButton(navbuttons,tr("\tShow icons\tDisplay directory with big icons."),iconsicon,filebox,FXFileList::ID_SHOW_BIG_ICONS,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMButton(navbuttons,tr("\tShow details\tDisplay detailed directory listing."),detailicon,filebox,FXFileList::ID_SHOW_DETAILS,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); new GMToggleButton(navbuttons,tr("\tShow hidden files\tShow hidden files and directories."),tr("\tHide Hidden Files\tHide hidden files and directories."),hiddenicon,shownicon,filebox,FXFileList::ID_TOGGLE_HIDDEN,TOGGLEBUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 3,3,3,3); bookmarks.setTarget(this); bookmarks.setSelector(ID_VISIT); readonly->hide(); if(table){ table->addAccel(MKUINT(KEY_BackSpace,0),this,FXSEL(SEL_COMMAND,ID_DIRECTORY_UP)); table->addAccel(MKUINT(KEY_Delete,0),this,FXSEL(SEL_COMMAND,ID_DELETE)); table->addAccel(MKUINT(KEY_h,CONTROLMASK),this,FXSEL(SEL_COMMAND,ID_HOME)); table->addAccel(MKUINT(KEY_w,CONTROLMASK),this,FXSEL(SEL_COMMAND,ID_WORK)); table->addAccel(MKUINT(KEY_n,CONTROLMASK),this,FXSEL(SEL_COMMAND,ID_NEW)); table->addAccel(MKUINT(KEY_a,CONTROLMASK),filebox,FXSEL(SEL_COMMAND,FXFileList::ID_SELECT_ALL)); table->addAccel(MKUINT(KEY_b,CONTROLMASK),filebox,FXSEL(SEL_COMMAND,FXFileList::ID_SHOW_BIG_ICONS)); table->addAccel(MKUINT(KEY_s,CONTROLMASK),filebox,FXSEL(SEL_COMMAND,FXFileList::ID_SHOW_MINI_ICONS)); table->addAccel(MKUINT(KEY_l,CONTROLMASK),filebox,FXSEL(SEL_COMMAND,FXFileList::ID_SHOW_DETAILS)); } setSelectMode(SELECTFILE_ANY); // For backward compatibility, this HAS to be the default! //setPatternList(allfiles); setDirectory(FXSystem::getCurrentDirectory()); filebox->setFocus(); accept->hide(); navigable=TRUE; fileassoc=new FXSettings(); filedict=new FXFileDict(getApp(),fileassoc); initFileDict(); #if FOXVERSION >= FXVERSION(1,7,11) filebox->setAssociations(filedict,false); dirbox->setAssociations(filedict,false); #else FXFileDict * old = filebox->getAssociations(); filebox->setAssociations(filedict); dirbox->setAssociations(filedict); delete old; #endif } GMFileSelector::~GMFileSelector(){ delete fileassoc; #if FOXVERSION >= FXVERSION(1,7,11) delete filedict; #endif } void GMFileSelector::hideButtons() { entryblock->childAtIndex(2)->hide(); cancel->hide(); } void GMFileSelector::getSelectedFiles(FXStringList & files) { if(selectmode==SELECTFILE_MULTIPLE_ALL){ for(FXint i=0; igetNumItems(); i++){ if(filebox->isItemSelected(i) && filebox->getItemFilename(i)!=".." && filebox->getItemFilename(i)!="."){ files.append(filebox->getItemPathname(i)); } } } else { /// implement me FXASSERT(0); } } static const FXchar * const filetypes[]={ "mp3",";MPEG-1 Audio Layer 3", "ogg",";Ogg Vorbis", "oga",";Ogg Audio", "flac",";Free Lossless Audio Codec", "wav",";Waveform Audio File Format", "mpc",";Musepack", #if defined(TAGLIB_WITH_ASF) && (TAGLIB_WITH_ASF==1) "wma",";Windows Media", "asf",";Windows Media", #endif #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) "m4a",";MPEG-4 Part 14", "m4b",";MPEG-4 Part 14", "m4p",";MPEG-4 Part 14", "aac",";MPEG-4 Part 14", #endif "m3u",";M3U Playlist", "pls",";PLS Playlist", "xspf",";XML Shareable Playlist" }; void GMFileSelector::initFileDict() { FXFileAssoc * assoc=NULL; const FXColor backcolor = FXApp::instance()->getBackColor(); GMIconTheme::instance()->loadSmall(icon_file_small,"text-x-generic",backcolor); GMIconTheme::instance()->loadMedium(icon_file_big,"text-x-generic",backcolor); GMIconTheme::instance()->loadSmall(icon_audio_small,"audio-x-generic",backcolor); GMIconTheme::instance()->loadMedium(icon_audio_big,"audio-x-generic",backcolor); GMIconTheme::instance()->loadSmall(icon_folder_small,"folder",backcolor); GMIconTheme::instance()->loadMedium(icon_folder_big,"folder",backcolor); for (FXuint i=0;ireplace(filetypes[i],filetypes[i+1]); assoc->bigicon = icon_audio_big; assoc->miniicon = icon_audio_small; assoc = filedict->replace(FXString(filetypes[i]).upper().text(),filetypes[i+1]); assoc->bigicon = icon_audio_big; assoc->miniicon = icon_audio_small; } assoc = filedict->replace(FXFileDict::defaultFileBinding,";"); assoc->bigicon = icon_file_big; assoc->miniicon = icon_file_small; assoc = filedict->replace(FXFileDict::defaultDirBinding,";"); assoc->bigicon = icon_folder_big; assoc->miniicon = icon_folder_small; } void GMDirSelector::initFileDict() { FXFileAssoc * assoc=NULL; const FXColor backcolor = FXApp::instance()->getBackColor(); GMIconTheme::instance()->loadSmall(icon_folder,"folder",backcolor); GMIconTheme::instance()->loadSmall(icon_folderopen,"folder-open",backcolor); assoc = filedict->replace(FXFileDict::defaultDirBinding,";"); assoc->miniiconopen = icon_folderopen; assoc->miniicon = icon_folder; } FXIMPLEMENT(GMFileDialog,FXFileDialog,NULL,0); // Construct file fialog box GMFileDialog::GMFileDialog(FXWindow* owner,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h): FXFileDialog(owner,name,opts,x,y,w,h){ delete filebox; filebox=new GMFileSelector(this,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); filebox->acceptButton()->setTarget(this); filebox->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); filebox->cancelButton()->setTarget(this); filebox->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); } // Construct free-floating file dialog box GMFileDialog::GMFileDialog(FXApp* a,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h): FXFileDialog(a,name,opts,x,y,w,h){ delete filebox; filebox=new GMFileSelector(this,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); filebox->acceptButton()->setTarget(this); filebox->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); filebox->cancelButton()->setTarget(this); filebox->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); } FXIMPLEMENT(GMExportDialog,GMFileDialog,NULL,0); // Construct file fialog box GMExportDialog::GMExportDialog(FXWindow* owner,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h): GMFileDialog(owner,name,opts,x,y,w,h){ GMFileSelector * fileselector = dynamic_cast(filebox); FXMatrix * entryblock = fileselector->optionFrame(); new FXLabel(entryblock,tr("&Options:"),NULL,JUSTIFY_LEFT|LAYOUT_CENTER_Y); check_relative=new GMCheckButton(entryblock,"Relative Paths",NULL,0,CHECKBUTTON_NORMAL|LAYOUT_FILL_COLUMN); new FXFrame(entryblock,FRAME_NONE); } // Construct free-floating file dialog box GMExportDialog::GMExportDialog(FXApp* a,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h): GMFileDialog(a,name,opts,x,y,w,h){ GMFileSelector * fileselector = dynamic_cast(filebox); FXMatrix * entryblock = fileselector->optionFrame(); new FXLabel(entryblock,tr("&Options:"),NULL,JUSTIFY_LEFT|LAYOUT_CENTER_Y); check_relative=new GMCheckButton(entryblock,"Relative Paths",NULL,0,CHECKBUTTON_NORMAL|LAYOUT_FILL_COLUMN); new FXFrame(entryblock,FRAME_NONE); } FXDEFMAP(GMImportDialog) GMImportDialogMap[]={ FXMAPFUNC(SEL_UPDATE,FXDialogBox::ID_ACCEPT,GMImportDialog::onUpdAccept), FXMAPFUNCS(SEL_UPDATE,GMImportDialog::ID_SYNC_NEW,GMImportDialog::ID_SYNC_REMOVE_ALL,GMImportDialog::onUpdSync), FXMAPFUNCS(SEL_COMMAND,GMImportDialog::ID_SYNC_NEW,GMImportDialog::ID_SYNC_REMOVE_ALL,GMImportDialog::onCmdSync), FXMAPFUNC(SEL_COMMAND,GMImportDialog::ID_PARSE_METHOD,GMImportDialog::onCmdParseMethod) }; FXIMPLEMENT(GMImportDialog,FXDialogBox,GMImportDialogMap,ARRAYNUMBER(GMImportDialogMap)) GMImportDialog::GMImportDialog(FXWindow *p,FXuint m) : FXDialogBox(p,FXString::null,DECOR_BORDER|DECOR_TITLE|DECOR_RESIZE,0,0,500,400,0,0,0,0,0,0), mode(m) { if (mode&IMPORT_SYNC) setTitle(tr("Synchronize Folder")); else if (mode&IMPORT_PLAYLIST) setTitle(tr("Import Playlist")); else setTitle(tr("Import Music")); /// Create a fixed font, about the same size as the normal font FXint size = FXApp::instance()->getNormalFont()->getSize(); font_fixed = new FXFont(FXApp::instance(),"mono",(int)size/10,FXFont::Normal,FXFont::Straight,FONTENCODING_UNICODE,FXFont::NonExpanded,FXFont::Modern|FXFont::Fixed); dirselector=NULL; fileselector=NULL; target_track_from_filelist.connect(GMPlayerManager::instance()->getPreferences().import.track_from_filelist); target_replace_underscores.connect(GMPlayerManager::instance()->getPreferences().import.replace_underscores); target_default_field.connect(GMPlayerManager::instance()->getPreferences().import.default_field); target_parse_method.connect(GMPlayerManager::instance()->getPreferences().import.parse_method,this,ID_PARSE_METHOD); target_filename_template.connect(GMPlayerManager::instance()->getPreferences().import.filename_template); target_exclude_dir.connect(GMPlayerManager::instance()->getPreferences().import.exclude_folder); target_exclude_file.connect(GMPlayerManager::instance()->getPreferences().import.exclude_file); const FXuint labelstyle=LAYOUT_CENTER_Y|LABEL_NORMAL|LAYOUT_RIGHT; const FXuint textfieldstyle=TEXTFIELD_ENTER_ONLY|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN; FXGroupBox * grpbox; FXMatrix * matrix; FXVerticalFrame * vframe; FXHorizontalFrame * hframe; FXVerticalFrame * main=new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y); GMTabBook * tabbook=new GMTabBook(main,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,0,0,0,0); if (mode&IMPORT_FROMFILE) { new GMTabItem(tabbook,tr("&File(s)"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); fileselector = new GMFileSelector(vframe,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); FXString searchdir = getApp()->reg().readStringEntry("directories","last-import-files",NULL); if (searchdir.empty()) getDefaultSearchDirectory(searchdir); if (mode&IMPORT_PLAYLIST) { fileselector->setPatternList(playlist_patterns); fileselector->setSelectMode(SELECTFILE_EXISTING); } else { fileselector->setPatternList(gmfilepatterns); fileselector->setSelectMode(SELECTFILE_MULTIPLE); } fileselector->setCurrentPattern(0); #if FOXVERSION < FXVERSION(1,7,20) fileselector->setMatchMode(FILEMATCH_CASEFOLD); #else fileselector->setMatchMode(FXPath::CaseFold); #endif fileselector->setDirectory(searchdir); fileselector->hideButtons(); fileselector->acceptButton()->setTarget(this); fileselector->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); fileselector->cancelButton()->setTarget(this); fileselector->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); } else if (mode&IMPORT_FROMDIR) { new GMTabItem(tabbook,tr("&Directory"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); GMCheckButton * excludetoggle = new GMCheckButton(vframe,tr("Exclude Filter\tFilter out directories and/or files based on pattern"),NULL,0,CHECKBUTTON_NORMAL|CHECKBUTTON_PLUS); matrix = new FXMatrix(vframe,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,16,4,0,0); new FXLabel(matrix,tr("Folders:"),NULL,labelstyle); new GMTextField(matrix,20,&target_exclude_dir,FXDataTarget::ID_VALUE,textfieldstyle); new FXLabel(matrix,tr("Files:"),NULL,labelstyle); new GMTextField(matrix,20,&target_exclude_file,FXDataTarget::ID_VALUE,textfieldstyle); excludetoggle->setTarget(matrix); excludetoggle->setSelector(FXWindow::ID_TOGGLESHOWN); if (GMPlayerManager::instance()->getPreferences().import.exclude_folder.empty() && GMPlayerManager::instance()->getPreferences().import.exclude_file.empty()) matrix->hide(); dirselector = new GMDirSelector(vframe,NULL,0,LAYOUT_FILL_X|LAYOUT_FILL_Y); FXString searchdir = getApp()->reg().readStringEntry("directories","last-import-dirs",NULL); if (searchdir.empty()) getDefaultSearchDirectory(searchdir); dirselector->setDirectory(searchdir); } if (mode&IMPORT_SYNC) { new GMTabItem(tabbook,tr("&Sync"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Sync Operation"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); new GMCheckButton(grpbox,tr("Import new tracks\tImports files not yet in the database."),this,ID_SYNC_NEW); new GMCheckButton(grpbox,tr("Remove tracks that have been deleted from disk"),this,ID_SYNC_REMOVE_MISSING); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); new GMCheckButton(matrix,tr("Update existing tracks:"),this,ID_SYNC_UPDATE); new FXRadioButton(matrix,tr("Modified since last import\tOnly reread the tag when the file has been modified."),this,ID_SYNC_UPDATE_MODIFIED,RADIOBUTTON_NORMAL|LAYOUT_CENTER_Y|LAYOUT_LEFT,0,0,0,0); new FXFrame(matrix,FRAME_NONE); new FXRadioButton(matrix,tr("All\tAlways read the tags"),this,ID_SYNC_UPDATE_ALL,RADIOBUTTON_NORMAL|LAYOUT_CENTER_Y|LAYOUT_LEFT,0,0,0,0); new GMCheckButton(grpbox,tr("Remove tracks found in folder from database"),this,ID_SYNC_REMOVE_ALL); } new GMTabItem(tabbook,tr("&Track"),NULL,TAB_TOP_NORMAL,0,0,0,0,5,5); vframe = new GMTabFrame(tabbook); grpbox = new FXGroupBox(vframe,tr("Parse Settings"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); grpbox->setFont(GMApp::instance()->getThickFont()); matrix = new FXMatrix(grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X); new FXLabel(matrix,tr("Parse info from:"),NULL,labelstyle); hframe = new FXHorizontalFrame(matrix,LAYOUT_FILL_COLUMN,0,0,0,0,0,0,0,0); new GMRadioButton(hframe,tr("Tag"),&target_parse_method,FXDataTarget::ID_OPTION+GMImportOptions::PARSE_TAG,JUSTIFY_LEFT|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y); new GMRadioButton(hframe,tr("Filename"),&target_parse_method,FXDataTarget::ID_OPTION+GMImportOptions::PARSE_FILENAME,JUSTIFY_LEFT|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y); new GMRadioButton(hframe,tr("Both"),&target_parse_method,FXDataTarget::ID_OPTION+GMImportOptions::PARSE_BOTH,JUSTIFY_LEFT|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y); new FXLabel(matrix,tr("Default value:"),NULL,labelstyle); new GMTextField(matrix,10,&target_default_field,FXDataTarget::ID_VALUE,textfieldstyle|LAYOUT_FILL_COLUMN); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,tr("Set track number based on scan order."),&target_track_from_filelist,FXDataTarget::ID_VALUE,LAYOUT_FILL_COLUMN|CHECKBUTTON_NORMAL); template_grpbox = new FXGroupBox(vframe,tr("Filename Template"),FRAME_NONE|LAYOUT_FILL_X,0,0,0,0,20); template_grpbox->setFont(GMApp::instance()->getThickFont()); FXLabel * label = new FXLabel(template_grpbox,tr("%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre"),NULL,FRAME_LINE|JUSTIFY_LEFT,0,0,0,0,30); label->setFont(font_fixed); label->setBackColor(getApp()->getTipbackColor()); label->setBorderColor(getApp()->getShadowColor()); new FXSeparator(template_grpbox,SEPARATOR_GROOVE|LAYOUT_FILL_X); matrix = new FXMatrix(template_grpbox,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X); new FXLabel(matrix,tr("Template:"),NULL,labelstyle); new GMTextField(matrix,10,&target_filename_template,FXDataTarget::ID_VALUE,textfieldstyle); new FXFrame(matrix,FRAME_NONE); new GMCheckButton(matrix,tr("Replace underscores with spaces"),&target_replace_underscores,FXDataTarget::ID_VALUE,CHECKBUTTON_NORMAL|LAYOUT_FILL_COLUMN); if (GMPlayerManager::instance()->getPreferences().import.parse_method==GMImportOptions::PARSE_TAG) { template_grpbox->hide(); } else { template_grpbox->show(); } FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0); if (mode&IMPORT_SYNC) new GMButton(closebox,tr("&Sync"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); else new GMButton(closebox,tr("&Import"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); new GMButton(closebox,tr("&Cancel"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); } long GMImportDialog::onCmdAccept(FXObject*sender,FXSelector sel,void*ptr){ return FXDialogBox::onCmdAccept(sender,sel,ptr); } long GMImportDialog::onUpdAccept(FXObject*sender,FXSelector,void*){ if (mode&IMPORT_SYNC) { if (GMPlayerManager::instance()->getPreferences().sync.import_new || GMPlayerManager::instance()->getPreferences().sync.remove_missing || GMPlayerManager::instance()->getPreferences().sync.update || GMPlayerManager::instance()->getPreferences().sync.remove_all) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); } else { sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); } return 1; } long GMImportDialog::onCmdSync(FXObject*,FXSelector sel,void*ptr){ FXbool check=((FXint)(FXival)ptr)!=0; switch(FXSELID(sel)){ case ID_SYNC_NEW : GMPlayerManager::instance()->getPreferences().sync.import_new=check; break; case ID_SYNC_REMOVE_MISSING : GMPlayerManager::instance()->getPreferences().sync.remove_missing=check; break; case ID_SYNC_UPDATE : GMPlayerManager::instance()->getPreferences().sync.update=check; break; case ID_SYNC_UPDATE_ALL : GMPlayerManager::instance()->getPreferences().sync.update_always=check; break; case ID_SYNC_UPDATE_MODIFIED: GMPlayerManager::instance()->getPreferences().sync.update_always=!check; break; case ID_SYNC_REMOVE_ALL : GMPlayerManager::instance()->getPreferences().sync.remove_all=check; break; } return 1; } long GMImportDialog::onUpdSync(FXObject*sender,FXSelector sel,void*){ FXbool enable=true; FXbool check=false; switch(FXSELID(sel)){ case ID_SYNC_NEW : check= (GMPlayerManager::instance()->getPreferences().sync.remove_all) ? false : GMPlayerManager::instance()->getPreferences().sync.import_new; enable=!GMPlayerManager::instance()->getPreferences().sync.remove_all; break; case ID_SYNC_REMOVE_MISSING : check= (GMPlayerManager::instance()->getPreferences().sync.remove_all) ? false : GMPlayerManager::instance()->getPreferences().sync.remove_missing; enable=!GMPlayerManager::instance()->getPreferences().sync.remove_all; break; case ID_SYNC_UPDATE : check= (GMPlayerManager::instance()->getPreferences().sync.remove_all) ? false : GMPlayerManager::instance()->getPreferences().sync.update; enable=!GMPlayerManager::instance()->getPreferences().sync.remove_all; break; case ID_SYNC_UPDATE_ALL : check= (GMPlayerManager::instance()->getPreferences().sync.remove_all) ? false : GMPlayerManager::instance()->getPreferences().sync.update_always; enable=(!GMPlayerManager::instance()->getPreferences().sync.remove_all && GMPlayerManager::instance()->getPreferences().sync.update); break; case ID_SYNC_UPDATE_MODIFIED: check= (GMPlayerManager::instance()->getPreferences().sync.remove_all) ? false : !GMPlayerManager::instance()->getPreferences().sync.update_always; enable=(!GMPlayerManager::instance()->getPreferences().sync.remove_all && GMPlayerManager::instance()->getPreferences().sync.update); break; case ID_SYNC_REMOVE_ALL : check=GMPlayerManager::instance()->getPreferences().sync.remove_all; break; } if (enable) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); if (check) sender->handle(this,FXSEL(SEL_COMMAND,ID_CHECK),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_UNCHECK),NULL); return 1; } void GMImportDialog::getSelectedFiles(FXStringList & files){ if (dirselector) { getApp()->reg().writeStringEntry("directories","last-import-dirs",dirselector->getDirectory().text()); files.append(dirselector->getDirectory()); } else if (fileselector){ getApp()->reg().writeStringEntry("directories","last-import-files",fileselector->getDirectory().text()); fileselector->getSelectedFiles(files); } } FXString GMImportDialog::getFilename() const{ getApp()->reg().writeStringEntry("directories","last-import-files",fileselector->getDirectory().text()); return fileselector->getFilename(); } long GMImportDialog::onCmdParseMethod(FXObject*,FXSelector,void*){ if (GMPlayerManager::instance()->getPreferences().import.parse_method==GMImportOptions::PARSE_TAG) { template_grpbox->hide(); } else { template_grpbox->show(); } template_grpbox->getParent()->recalc(); template_grpbox->getParent()->layout(); return 1; } void GMImportDialog::getDefaultSearchDirectory(FXString & directory){ const FXchar * musicdir[]={ "Music", "music", "mp3", "MP3", "Mp3", "ogg", "OGG", "Ogg", "wav", #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) "mp4", "MP4", "Mp4", #endif NULL }; FXString test; FXString home=FXSystem::getHomeDirectory(); for (int i=0;musicdir[i]!=NULL;i++){ test = home + PATHSEPSTRING + musicdir[i]; if (FXStat::exists(test) && FXStat::isDirectory(test)){ directory=test; break; } } if (directory.empty()) directory=home; } gogglesmm-0.12.7/src/GMEQDialog.cpp0000644000175000001440000003711611525430601015456 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "icons.h" #include #include #include "GMPlayer.h" #include "GMTrackList.h" #include "GMList.h" #include "GMRemote.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMTrackDatabase.h" #include "GMDatabaseSource.h" #include "GMTrackView.h" #include "GMSourceView.h" #include "GMIconTheme.h" #include "GMEQDialog.h" #include "GMWindow.h" const FXchar * default_presets[]={ "Classical,0,0,0,0,0,0,-2.4,-2.4,-2.4,-3.0", "Club, 0,0,1.2,1.8,1.8,1.8,1.2,0,0,0", "Dance,3.0,2.1,0.6,0,0,-1.8,-2.4,-2.4,0,0", "Full Bass,4.2,4.2,4.2,2.4,1.2,-1.2,-2.7,-3.0,-3.3,-3.3", "Full Treble,-3.0,-3.0,-3.0,-1.5,0.9,3.3,4.8,4.8,4.8,5.1", "Full Bass+Treble,2.1,1.8,0,-2.4,-1.5,0.6,2.7,3.3,3.6,3.6", "Laptop/Headphones,1.5,3.0,1.5,-1.2,0,-1.8,-2.4,-2.4,0,0", "Large Hall,3.0,3.0,1.8,1.8,0,-1.5,-1.5,-1.5,0,0", "Live,-1.5,0,1.2,1.5,1.8,1.8,1.2,0.9,0.9,0.6", "Party,2.1,2.1,0,0,0,0,0,0,2.1,2.1", "Pop,-0.6,1.5,2.1,2.4,1.5,-0.3,-0.9,-0.9,-0.6,-0.6", "Reggae,0,0,-0.3,-1.8,0,-2.1,-2.1,0,0,0", "Rock,2.4,1.5,-1.8,-2.4,-1.2,1.2,2.7,3.3,3.3,3.3", "Soft,1.5,0.6,-0.3,-0.9,-0.3,1.2,2.7,3.0,3.3,3.6", "Ska,-0.9,-1.5,-1.5,-0.3,1.2,1.8,2.7,3.0,3.3,3.0", "Soft Rock,1.2,1.2,0.6,-0.3,-1.5,-1.8,-1.2,-0.3,0.9,2.7", "Techno,2.4,1.8,0,-1.8,-1.5,0,2.4,3.0,3.0,2.7", "Zero,0,0,0,0,0,0,0,0,0,0" }; GMEQDialog * GMEQDialog::myself = NULL; FXDEFMAP(GMEQDialog) GMEQDialogMap[]={ FXMAPFUNCS(SEL_UPDATE,GMEQDialog::ID_EQ_30HZ,GMEQDialog::ID_EQ_16000HZ,GMEQDialog::onUpdEQ), FXMAPFUNCS(SEL_COMMAND,GMEQDialog::ID_EQ_30HZ,GMEQDialog::ID_EQ_16000HZ,GMEQDialog::onCmdEQ), FXMAPFUNCS(SEL_CHANGED,GMEQDialog::ID_EQ_30HZ,GMEQDialog::ID_EQ_16000HZ,GMEQDialog::onCmdEQ), FXMAPFUNC(SEL_COMMAND,GMEQDialog::ID_PRESET_EQ,GMEQDialog::onCmdPresetEQ), #if FOXVERSION >= FXVERSION(1,7,0) FXMAPFUNC(SEL_CHANGED,GMEQDialog::ID_PRESET_EQ,GMEQDialog::onCmdPresetEQ), #endif FXMAPFUNC(SEL_COMMAND,GMEQDialog::ID_RESET,GMEQDialog::onCmdReset), FXMAPFUNC(SEL_COMMAND,GMEQDialog::ID_SAVE,GMEQDialog::onCmdSave), FXMAPFUNC(SEL_COMMAND,GMEQDialog::ID_DELETE,GMEQDialog::onCmdDelete), FXMAPFUNC(SEL_UPDATE,GMEQDialog::ID_RESET,GMEQDialog::onUpdReset), FXMAPFUNC(SEL_UPDATE,GMEQDialog::ID_SAVE,GMEQDialog::onUpdSave), FXMAPFUNC(SEL_UPDATE,GMEQDialog::ID_DELETE,GMEQDialog::onUpdDelete), }; FXIMPLEMENT(GMEQDialog,FXDialogBox,GMEQDialogMap,ARRAYNUMBER(GMEQDialogMap)) GMEQDialog::GMEQDialog(FXWindow * p) : FXDialogBox(p,FXString::null,DECOR_BORDER|DECOR_TITLE|DECOR_CLOSE,0,0,0,0,2,2,2,2) { FXASSERT(myself==NULL); myself=this; //FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0); // new FXButton(closebox,tr("&Close"),NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); //new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM); setTitle(tr("Equalizer")); /// Create a fixed font, about the same size as the normal font FXint size = FXApp::instance()->getNormalFont()->getSize() - 10; font_small = new FXFont(FXApp::instance(),"mono",(int)size/10,FXFont::Normal,FXFont::Straight,FONTENCODING_UNICODE,FXFont::NonExpanded,FXFont::Modern|FXFont::Fixed); FXRealSlider *slider; FXLabel * label; FXTextField * textfield; { FXStringDict * dict = getApp()->reg().find("equalizer-presets"); /// Add default presets if they don't exist. if (!dict || dict->no()==0){ for (FXint i=0;i<(FXint)ARRAYNUMBER(default_presets);i++){ getApp()->reg().writeStringEntry("equalizer-presets",GMStringVal(i).text(),default_presets[i]); } } FXString entry; dict = getApp()->reg().find("equalizer-presets"); if (dict && dict->no()>0) { presets.no(dict->no()); for (FXint pos=dict->first(),i=0;possize();pos=dict->next(pos),i++){ entry=dict->data(pos); presets[i].name = entry.section(',',0); presets[i].bands.parse(entry.after(',',1)); } } } FXHorizontalFrame * presetframe = new FXHorizontalFrame(this,LAYOUT_FILL_X,0,0,0,0,0,0,0,0); new FXLabel(presetframe,tr("Equalizer:"),NULL,LAYOUT_CENTER_Y); presetlist = new GMListBox(presetframe,this,ID_PRESET_EQ,LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK); new FXButton(presetframe,tr("\tSave"),GMIconTheme::instance()->icon_export,this,ID_SAVE,FRAME_RAISED|BUTTON_TOOLBAR); new FXButton(presetframe,tr("\tReset"),GMIconTheme::instance()->icon_undo,this,ID_RESET,FRAME_RAISED|BUTTON_TOOLBAR); new FXButton(presetframe,tr("\tRemove"),GMIconTheme::instance()->icon_delete,this,ID_DELETE,FRAME_RAISED|BUTTON_TOOLBAR); listPresets(); const FXuint sliderstyle = LAYOUT_FILL_Y|SLIDER_VERTICAL|LAYOUT_CENTER_X|SLIDER_TICKS_LEFT|SLIDER_TICKS_RIGHT|LAYOUT_FILL_ROW; const FXchar * labels[]={"30","60","125","250","500","1k","2k","4k","8k","16k"}; new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE); FXMatrix * eqmatrix = new FXMatrix(this,3,MATRIX_BY_ROWS|LAYOUT_CENTER_X|LAYOUT_CENTER_Y|LAYOUT_FIX_HEIGHT,0,0,0,200,0,0,0,0,3,2); new FXFrame(eqmatrix,FRAME_NONE); FXVerticalFrame * vframe = new FXVerticalFrame(eqmatrix,LAYOUT_FILL_Y|LAYOUT_FILL_ROW,0,0,0,0,0,0,0,0,0,0); label = new FXLabel(vframe,"+12db",NULL,LAYOUT_TOP|LAYOUT_RIGHT,0,0,0,0,2,2,0,0); label->setFont(font_small); label = new FXLabel(vframe,"0",NULL,LAYOUT_CENTER_Y|LAYOUT_RIGHT,0,0,0,0,2,2,0,0); label->setFont(font_small); label = new FXLabel(vframe,"-12db",NULL,LAYOUT_BOTTOM|LAYOUT_RIGHT,0,0,0,0,2,2,0,0); label->setFont(font_small); new FXFrame(eqmatrix,FRAME_NONE); textfield=new FXTextField(eqmatrix,4,GMPlayerManager::instance()->getPlayer(),GMPlayer::ID_PREAMP,LAYOUT_CENTER_X|TEXTFIELD_INTEGER|FRAME_SUNKEN|JUSTIFY_RIGHT,0,0,0,0,2,2,0,0); textfield->setFont(font_small); FXRealSlider * rslider = new FXRealSlider(eqmatrix,GMPlayerManager::instance()->getPlayer(),GMPlayer::ID_PREAMP,sliderstyle,0,0,0,0,0,0,0,0); rslider->setRange(-12.0,12.0); rslider->setTickDelta(12.0); rslider->setIncrement(1); rslider->setValue(0.0); label = new FXLabel(eqmatrix,tr("Pre-amp"),NULL,LAYOUT_CENTER_X,0,0,0,0,2,2,0,0); label->setFont(font_small); for (FXint i=0;i<10;i++) { textfield = new FXTextField(eqmatrix,4,this,ID_EQ_30HZ+i,LAYOUT_CENTER_X|TEXTFIELD_REAL|FRAME_SUNKEN|JUSTIFY_RIGHT,0,0,0,0,2,2,0,0); textfield->setFont(font_small); slider = new FXRealSlider(eqmatrix,this,ID_EQ_30HZ+i,sliderstyle,0,0,0,0,0,0,0,0); slider->setRange(-6,6); slider->setTickDelta(6); slider->setIncrement(0.5); #if FOXVERSION >= FXVERSION(1,7,0) slider->setGranularity(0.1); #endif slider->setValue(0); eqslider[i]=slider; FXLabel * label = new FXLabel(eqmatrix,labels[i],NULL,LAYOUT_CENTER_X,0,0,0,0,2,2,0,0); label->setFont(font_small); } new FXFrame(eqmatrix,FRAME_NONE); vframe = new FXVerticalFrame(eqmatrix,LAYOUT_FILL_Y|LAYOUT_FILL_ROW,0,0,0,0,0,0,0,0,0,0); label = new FXLabel(vframe,"+6db",NULL,LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,2,2,0,0); label->setFont(font_small); label = new FXLabel(vframe,"0",NULL,LAYOUT_CENTER_Y|LAYOUT_LEFT,0,0,0,0,2,2,0,0); label->setFont(font_small); label = new FXLabel(vframe,"-6db",NULL,LAYOUT_BOTTOM|LAYOUT_LEFT,0,0,0,0,2,2,0,0); label->setFont(font_small); new FXFrame(eqmatrix,FRAME_NONE); if (getApp()->reg().readIntEntry("eqdialog","x",-1)!=-1) { FXint xx=getApp()->reg().readIntEntry("eqdialog","x",getX()); FXint yy=getApp()->reg().readIntEntry("eqdialog","y",getY()); move(xx,yy); } else { place(PLACEMENT_OWNER); } } GMEQDialog::~GMEQDialog(){ myself=NULL; FXString entry; getApp()->reg().deleteSection("equalizer-presets"); for (FXint i=0;ireg().writeFormatEntry("equalizer-presets",GMStringVal(i).text(),"%s,%s",presets[i].name.text(),entry.text()); } } void GMEQDialog::listPresets() { for (FXint i=0;iappendItem(presets[i].name,NULL,(void*)(FXival)(i+1)); } GMEqualizer eq; GMPlayerManager::instance()->getPlayer()->getEqualizer(eq); if (eq.enabled) { FXbool found=false; for (FXint i=0;!found && isetCurrentItem(i); found=true; } } presetlist->setSortFunc(FXList::ascending); presetlist->sortItems(); presetlist->prependItem(tr("Disabled")); if (!found) { presetlist->insertItem(1,tr("Manual"),NULL,(void*)(FXival)-1); presetlist->setCurrentItem(1); } } else { presetlist->setSortFunc(FXList::ascending); presetlist->sortItems(); presetlist->prependItem(tr("Disabled")); presetlist->setCurrentItem(0); } presetlist->setNumVisible(FXMIN(9,presetlist->getNumItems())); } void GMEQDialog::hide() { FXDialogBox::hide(); /// Save Position getApp()->reg().writeIntEntry("eqdialog","x",getX()); getApp()->reg().writeIntEntry("eqdialog","y",getY()); delete this; } GMEQDialog * GMEQDialog::instance() { return myself; } long GMEQDialog::onCmdEQ(FXObject*sender,FXSelector sel,void*ptr){ long result = GMPlayerManager::instance()->getPlayer()->handle(sender,FXSEL(FXSELTYPE(sel),GMPlayer::ID_EQ_30HZ+(FXSELID(sel)-ID_EQ_30HZ)),ptr); GMEqualizer eq; GMPlayerManager::instance()->getPlayer()->getEqualizer(eq); if (eq.enabled) { FXbool found=false; for (FXint i=0;!found && isetCurrentItem(presetlist->findItemByData((void*)(FXival)(i+1))); FXint item = presetlist->findItemByData((void*)(FXival)(-1)); if (item>=0) presetlist->removeItem(item); found=true; } } if (!found) { FXint item = presetlist->findItemByData((void*)(FXival)(-1)); if (item>=0) { presetlist->setCurrentItem(item); } else { presetlist->insertItem(1,tr("Manual"),NULL,(void*)(FXival)-1); presetlist->setCurrentItem(1); } } } return result; } long GMEQDialog::onUpdEQ(FXObject*sender,FXSelector sel,void*ptr){ return GMPlayerManager::instance()->getPlayer()->handle(sender,FXSEL(SEL_UPDATE,GMPlayer::ID_EQ_30HZ+(FXSELID(sel)-ID_EQ_30HZ)),ptr); } long GMEQDialog::onCmdDelete(FXObject*,FXSelector,void*){ FXint p = ((FXint)(FXival)presetlist->getItemData(presetlist->getCurrentItem()))-1; if (FXMessageBox::question(this,MBOX_YES_NO,tr("Delete Preset"),fxtrformat("Are you sure you want to delete %s preset?"),presets[p].name.text())==MBOX_CLICKED_YES){ presets.erase(p); presetlist->clearItems(); listPresets(); } return 1; } long GMEQDialog::onUpdDelete(FXObject*sender,FXSelector,void*){ FXint p = (FXint)(FXival)presetlist->getItemData(presetlist->getCurrentItem()); if (0handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMEQDialog::onCmdSave(FXObject*,FXSelector,void*){ FXString name; if (FXInputDialog::getString(name,this,tr("Preset Name"),tr("Please enter preset name:"),NULL)){ if (!name.empty()) { for (FXint i=0;igetValue(); } } /// cancel return 1; } } /// Everything ok presets.no(presets.no()+1); presets[presets.no()-1].name=name; for (FXint b=0;b<10;b++){ presets[presets.no()-1].bands[b]=eqslider[b]->getValue(); } presetlist->appendItem(name,NULL,(void*)(FXival)(presets.no())); presetlist->setCurrentItem(presetlist->getNumItems()-1); presetlist->setNumVisible(FXMIN(9,presetlist->getNumItems())); presetlist->sortItems(); presetlist->moveItem(0,presetlist->findItemByData(NULL)); } } return 1; } long GMEQDialog::onUpdSave(FXObject*sender,FXSelector,void*){ FXint p = (FXint)(FXival)presetlist->getItemData(presetlist->getCurrentItem()); if (p!=0) sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } long GMEQDialog::onCmdReset(FXObject*,FXSelector,void*){ FXint p = (FXint)(FXival)presetlist->getItemData(presetlist->getCurrentItem()); FXString entry; for (FXint i=0;i<(FXint)ARRAYNUMBER(default_presets);i++){ entry = default_presets[i]; if (presets[p-1].name==entry.before(',')){ presets[p-1].bands.parse(entry.after(',',1)); GMPlayerManager::instance()->getPlayer()->setEqualizer(presets[p-1].bands); for (FXint i=0;i<10;i++){ eqslider[i]->setValue(presets[p-1].bands[i]); } break; } } return 1; } long GMEQDialog::onUpdReset(FXObject*sender,FXSelector,void*){ FXint p = (FXint)(FXival)presetlist->getItemData(presetlist->getCurrentItem()); if (0handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL); else sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL); return 1; } #if FOXVERSION >= FXVERSION(1,7,0) long GMEQDialog::onCmdPresetEQ(FXObject*sender,FXSelector sel,void*ptr){ GMListBox * list = reinterpret_cast(sender); if (FXSELTYPE(sel)==SEL_CHANGED && list->isMenuShown()) return 1; #else long GMEQDialog::onCmdPresetEQ(FXObject*sender,FXSelector,void*ptr){ GMListBox * list = reinterpret_cast(sender); #endif FXint item = (FXint)(FXival)ptr; FXint p = ((FXint)(FXival)list->getItemData(item))-1; if (p>=0) { GMPlayerManager::instance()->getPlayer()->setEqualizer(presets[p].bands); for (FXint i=0;i<10;i++){ eqslider[i]->setValue(presets[p].bands[i]); } item = presetlist->findItemByData((void*)(FXival)(-1)); if (item>=0) presetlist->removeItem(item); } else if (p==-1) { GMPlayerManager::instance()->getPlayer()->disableEqualizer(); item = presetlist->findItemByData((void*)(FXival)(-1)); if (item>=0) presetlist->removeItem(item); } return 1; } gogglesmm-0.12.7/src/GMFontDialog.cpp0000644000175000001440000003731011525430601016053 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2009-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMList.h" #include "GMFontDialog.h" FXDEFMAP(GMFontDialog) GMFontDialogMap[]={ FXMAPFUNC(SEL_UPDATE,GMFontDialog::ID_PITCH,GMFontDialog::onUpdPitch), FXMAPFUNC(SEL_UPDATE,GMFontDialog::ID_SCALABLE,GMFontDialog::onUpdScalable), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_PITCH,GMFontDialog::onCmdPitch), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SCALABLE,GMFontDialog::onCmdScalable), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_FAMILY,GMFontDialog::onCmdFamily), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_STYLE,GMFontDialog::onCmdStyle), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SIZE,GMFontDialog::onCmdSize), FXMAPFUNC(SEL_COMMAND,GMFontDialog::ID_SIZE_TEXT,GMFontDialog::onCmdSizeText) }; FXIMPLEMENT(GMFontDialog,FXDialogBox,GMFontDialogMap,ARRAYNUMBER(GMFontDialogMap)) GMFontDialog::GMFontDialog() { } GMFontDialog::GMFontDialog(FXApp * app,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h) : FXDialogBox(app,name,opts,x,y,w,h,3,3,3,3) , previewfont(NULL) { } GMFontDialog::GMFontDialog(FXWindow* owner,const FXString& name,FXuint opts,FXint x,FXint y,FXint w,FXint h) : FXDialogBox(owner,name,opts,x,y,w,h,4,4,4,4),previewfont(NULL) { GMScrollFrame *sunken; // FXVerticalFrame * frm; FXHorizontalFrame *closebox=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,2,2); new GMButton(closebox," &Accept",NULL,this,FXDialogBox::ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); new GMButton(closebox," &Cancel ",NULL,this,FXDialogBox::ID_CANCEL,BUTTON_DEFAULT|LAYOUT_RIGHT|FRAME_RAISED|FRAME_THICK,0,0,0,0, 15,15); FXVerticalFrame * main = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); //frm=new FXVerticalFrame(main,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK|LAYOUT_BOTTOM,0,0,0,0,0,0,0,0); sunken=new GMScrollFrame(main); sunken->setLayoutHints(LAYOUT_BOTTOM|LAYOUT_FILL_X|LAYOUT_FILL_Y); FXScrollWindow *scroll=new FXScrollWindow(sunken,LAYOUT_FILL_X|LAYOUT_FILL_Y); GMScrollArea::replaceScrollbars(scroll); preview=new FXLabel(scroll,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789",NULL,LAYOUT_CENTER_X|LAYOUT_CENTER_Y); preview->setBackColor(getApp()->getBackColor()); // new FXLabel(main,"Preview:",NULL,LAYOUT_BOTTOM); FXHorizontalFrame * filterframe = new FXHorizontalFrame(main,LAYOUT_FILL_X|LAYOUT_BOTTOM,0,0,0,0,0,0,3,3,0,0); new FXLabel(filterframe,"Pitch:",NULL,LABEL_NORMAL|LAYOUT_CENTER_Y,0,0,0,0); pitchlist = new GMListBox(filterframe,this,ID_PITCH); pitchlist->appendItem("Any"); pitchlist->appendItem("Fixed",NULL,(void*)(FXuval)FXFont::Fixed); pitchlist->appendItem("Variable",NULL,(void*)(FXuval)FXFont::Variable); pitchlist->setNumVisible(3); new FXLabel(filterframe," Type:",NULL,LABEL_NORMAL|LAYOUT_CENTER_Y); scalelist = new GMListBox(filterframe,this,ID_SCALABLE); scalelist->appendItem("Any"); scalelist->appendItem("Scalable",NULL,(void*)(FXuval)FXFont::Scalable); scalelist->setNumVisible(2); FXHorizontalFrame * input = new FXHorizontalFrame(main,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0); FXVerticalFrame * sizeframe = new FXVerticalFrame(input,LAYOUT_RIGHT|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); new FXLabel(sizeframe,"Size:",NULL,LABEL_NORMAL,0,0,0,0,0,0); FXVerticalFrame * sizeinputframe = new FXVerticalFrame(sizeframe,LAYOUT_RIGHT|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0); sizefield=new GMTextField(sizeinputframe,3,this,ID_SIZE_TEXT,TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X); sunken=new GMScrollFrame(sizeinputframe); sizelist=new GMList(sunken,this,ID_SIZE,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_SINGLESELECT); FXHorizontalFrame * mainframe = new FXHorizontalFrame(input,LAYOUT_LEFT|LAYOUT_FILL_Y|LAYOUT_FILL_X,0,0,0,0,0,0,0,0); FXSpring * familyframe = new FXSpring(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y,4,0,0,0,0,0,0,0,0,0,0,0); new FXLabel(familyframe,"Family:",NULL,LABEL_NORMAL,0,0,0,0); sunken=new GMScrollFrame(familyframe); familylist = new GMList(sunken,this,ID_FAMILY,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_BROWSESELECT); familylist->setSortFunc(FXList::ascending); FXSpring * styleframe = new FXSpring(mainframe,LAYOUT_FILL_X|LAYOUT_FILL_Y,3,0,0,0,0,0,0,0,0,0,0,0); new FXLabel(styleframe,"Style:",NULL,LABEL_NORMAL,0,0,0,0); sunken=new GMScrollFrame(styleframe); stylelist=new GMList(sunken,this,ID_STYLE,LAYOUT_FILL_Y|LAYOUT_FILL_X|LIST_BROWSESELECT); stylelist->setSortFunc(FXList::ascending); #if FOXVERSION < FXVERSION(1,7,17) getApp()->getNormalFont()->getFontDesc(selected); #else selected = getApp()->getNormalFont()->getActualFontDesc(); #endif selected.flags|=FXFont::Scalable; } GMFontDialog::~GMFontDialog(){ } void GMFontDialog::setFontDesc(const FXFontDesc& fontdesc){ selected=fontdesc; } const FXFontDesc& GMFontDialog::getFontDesc() const { return selected; } void GMFontDialog::create() { FXDialogBox::create(); listFontFamily(); listFontStyle(); listFontSize(); } // Preview void GMFontDialog::previewFont(){ FXFont *old; // Save old font old=previewfont; // Get new font previewfont=new FXFont(getApp(),selected); // Realize new font previewfont->create(); // Set new font preview->setFont(previewfont); /* FXString previewtext; for (FXwchar w=previewfont->getMinChar();w<=previewfont->getMaxChar()&& previewtext.length()<64;w++) { if (previewfont->hasChar(w)) { previewtext.append(&w,1); } if (previewtext.length()==26) previewtext+="\n"; if (previewtext.length()==53) previewtext+="\n"; } preview->setText(previewtext); */ // Delete old font delete old; } void GMFontDialog::listFontFamily(){ FXFontDesc * fonts=NULL; FXuint numfonts,f; FXint last=-1,selindex=-1; FXString face,family,pfamily; familylist->clearItems(); if (FXFont::listFonts(fonts,numfonts,FXString::null,0,0,0,selected.encoding,selected.flags)) { for(f=0;f=0) { familylist->setItemText(last,fonts[f-1].face); last=familylist->appendItem(fonts[f].face,NULL,(void*)(FXuval)fonts[f].flags); } else { last=familylist->appendItem(family,NULL,(void*)(FXuval)fonts[f].flags); } pfamily.adopt(family); if(compare(selected.face,fonts[f].face)==0) selindex=f; } if(selindex==-1) selindex=0; if(0getNumItems()){ familylist->setCurrentItem(selindex); familylist->makeItemVisible(selindex); strncpy(selected.face,familylist->getItemText(selindex).text(),sizeof(selected.face)); } FXFREE(&fonts); } familylist->sortItems(); } void GMFontDialog::listFontStyle(){ FXFontDesc * fonts=NULL; FXint selindex=-1; FXuint numfonts,f; FXushort wi,ww,lastwi=0,lastww=0,sl,lastsl=0; const FXchar *wgt=NULL,*slt=NULL,*wid=NULL; stylelist->clearItems(); if (FXFont::listFonts(fonts,numfonts,selected.face,0,0,0/*selected.weight,selected.slant,selected.setwidth*/,selected.encoding,selected.flags)) { for(f=0;fappendItem(GMStringFormat("%s %s %s",wgt,wid,slt),NULL,(void*)(FXuval)style); else if (wgt && slt) stylelist->appendItem(GMStringFormat("%s %s",wgt,slt),NULL,(void*)(FXuval)style); else if (wgt && wid) stylelist->appendItem(GMStringFormat("%s %s",wgt,wid),NULL,(void*)(FXuval)style); else if (wid && slt) stylelist->appendItem(GMStringFormat("%s %s",wid,slt),NULL,(void*)(FXuval)style); else if (slt) stylelist->appendItem(tr(slt),NULL,(void*)(FXuval)style); else if (wgt) stylelist->appendItem(tr(wgt),NULL,(void*)(FXuval)style); else if (wid) stylelist->appendItem(tr(wid),NULL,(void*)(FXuval)style); else stylelist->appendItem(tr("Normal"),NULL,(void*)(FXuval)style); if (ww==selected.weight && sl==selected.slant && wi==selected.setwidth) { selindex=stylelist->getNumItems()-1; } } } FXFREE(&fonts); if(selindex==-1) selindex=0; if(0getNumItems()){ stylelist->setCurrentItem(selindex); FXuint style=(FXuint)(FXuval)stylelist->getItemData(selindex); selected.weight=FXREDVAL(style); selected.slant=FXGREENVAL(style); selected.setwidth=FXBLUEVAL(style); stylelist->makeItemVisible(selindex); //stylelist->sortItems(); } } } void GMFontDialog::listFontSize(){ const FXuint sizeint[]={60,80,90,100,110,120,140,160,200,240,300,360,420,480,640,720}; FXFontDesc *fonts; FXuint numfonts,f,s,lasts; FXint selindex=-1; sizelist->clearItems(); sizefield->setText(FXString::null); FXString string; if(FXFont::listFonts(fonts,numfonts,selected.face,selected.weight,selected.slant,selected.setwidth,selected.encoding,selected.flags)){ FXASSERT(0getListStyle(); style&=~LIST_BROWSESELECT; style|=LIST_SINGLESELECT; sizelist->setListStyle(style); for(f=0; fappendItem(string,NULL,(void*)(FXuval)s); if(selected.size == s) selindex=sizelist->getNumItems()-1; lasts=s; } } else{ FXuint style=sizelist->getListStyle(); style&=~LIST_SINGLESELECT; style|=LIST_BROWSESELECT; sizelist->setListStyle(style); for(f=0; fappendItem(string,NULL,(void*)(FXuval)s); if(selected.size==s) selindex=sizelist->getNumItems()-1; lasts=s; } } } if(selindex==-1) selindex=0; if(0getNumItems()){ sizelist->selectItem(selindex); sizelist->makeItemVisible(selindex); sizefield->setText(sizelist->getItemText(selindex)); selected.size=(FXuint)(FXuval)sizelist->getItemData(selindex); } FXFREE(&fonts); } } long GMFontDialog::onCmdFamily(FXObject*,FXSelector,void* ptr){ strncpy(selected.face,familylist->getItemText((FXint)(FXival)ptr).text(),sizeof(selected.face)); listFontStyle(); listFontSize(); previewFont(); return 1; } long GMFontDialog::onCmdStyle(FXObject*,FXSelector,void* ptr){ FXuint style=(FXuint)(FXuval)stylelist->getItemData((FXint)(FXival)ptr); selected.weight=FXREDVAL(style); selected.slant=FXGREENVAL(style); selected.setwidth=FXBLUEVAL(style); listFontSize(); previewFont(); return 1; } long GMFontDialog::onCmdSize(FXObject*,FXSelector,void*ptr){ selected.size=(FXuint)(FXuval)sizelist->getItemData((FXint)(FXival)ptr); sizefield->setText(sizelist->getItemText((FXint)(FXival)ptr)); previewFont(); return 1; } long GMFontDialog::onCmdSizeText(FXObject*,FXSelector,void*){ selected.size=(FXuint)(10.0*GMFloatVal(sizefield->getText())); if(selected.size<60) selected.size=60; if(selected.size>2400) selected.size=2400; previewFont(); return 1; } // Changed pitch long GMFontDialog::onCmdPitch(FXObject*,FXSelector,void*ptr){ FXint index=(FXint)(FXival)ptr; selected.flags&=~(FXFont::Fixed|FXFont::Variable); selected.flags|=(FXuint)(FXuval)pitchlist->getItemData(index); listFontFamily(); listFontStyle(); listFontSize(); previewFont(); return 1; } long GMFontDialog::onUpdPitch(FXObject*sender,FXSelector,void*){ FXint value=(selected.flags&FXFont::Fixed) ? 1 : (selected.flags&FXFont::Variable) ? 2 : 0; sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&value); return 1; } // Changed pitch long GMFontDialog::onCmdScalable(FXObject*,FXSelector,void*ptr){ FXint index=(FXint)(FXival)ptr; selected.flags&=~(FXFont::Scalable); selected.flags|=(FXuint)(FXuval)scalelist->getItemData(index); listFontFamily(); listFontStyle(); listFontSize(); previewFont(); return 1; } long GMFontDialog::onUpdScalable(FXObject*sender,FXSelector,void*){ FXint value=(selected.flags&FXFont::Scalable) ? 1 : 0; sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&value); return 1; } gogglesmm-0.12.7/src/md5.h0000644000175000001440000000650011433501277013736 0ustar sxjusers/* Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed references to Ghostscript; clarified derivation from RFC 1321; now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ #ifndef md5_INCLUDED # define md5_INCLUDED /* * This package supports both compile-time and run-time determination of CPU * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is * defined as non-zero, the code will be compiled to run only on big-endian * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to * run on either big- or little-endian CPUs, but will run slightly less * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. */ typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t abcd[4]; /* digest buffer */ md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; #ifdef __cplusplus extern "C" { #endif /* Initialize the algorithm. */ void md5_init(md5_state_t *pms); /* Append a string to the message. */ void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); /* Finish the message and return the digest. */ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ #endif #endif /* md5_INCLUDED */ gogglesmm-0.12.7/src/GMTag.cpp0000644000175000001440000011357211644106413014550 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(TAGLIB_WITH_MP4) && (TAGLIB_WITH_MP4==1) #define TAGLIB_HAVE_MP4 1 #endif #ifdef TAGLIB_HAVE_MP4 #include "mp4file.h" #include "mp4tag.h" #include "mp4coverart.h" #endif #ifndef TAGLIB_MAJOR_VERSION #error "missing taglib_major_version" #endif #define MKVERSION(major,minor,release) ((release)+(minor*1000)+(major*1000000)) #define TAGLIB_VERSION MKVERSION(TAGLIB_MAJOR_VERSION,TAGLIB_MINOR_VERSION,TAGLIB_PATCH_VERSION) #include "gmdefs.h" #include "gmutils.h" #include "GMTag.h" #include "FXPNGImage.h" #include "FXJPGImage.h" static GMCover * id3v2_load_cover(TagLib::ID3v2::AttachedPictureFrame * frame,FXint scale) { FXString mime = frame->mimeType().toCString(true); /// Skip File Icon if (frame->type()==TagLib::ID3v2::AttachedPictureFrame::FileIcon || frame->type()==TagLib::ID3v2::AttachedPictureFrame::OtherFileIcon || frame->type()==TagLib::ID3v2::AttachedPictureFrame::ColouredFish) { return NULL; } FXImage * image = gm_load_image_from_data(frame->picture().data(),frame->picture().size(),mime,scale); if (image) return new GMCover(image,frame->type()); return NULL; } static FXbool id3v2_is_front_cover(TagLib::ID3v2::AttachedPictureFrame * frame){ if (frame->type()==TagLib::ID3v2::AttachedPictureFrame::FrontCover) return true; else return false; } /******************************************************************************/ /* HELPER CLASS TO ACCESS ADDITIONAL TAGS FROM FILE */ /******************************************************************************/ class GMFileTag { public: TagLib::File * file; TagLib::Tag * tag; #ifdef TAGLIB_HAVE_MP4 TagLib::MP4::Tag * mp4; #else void * mp4; #endif TagLib::Ogg::XiphComment * xiph; TagLib::ID3v2::Tag * id3v2; TagLib::APE::Tag * ape; protected: void xiph_update_field(const FXchar * field,const FXString & value); void xiph_update_field(const FXchar * field,const FXStringList & value); void id3v2_update_field(const FXchar * field,const FXString & value); void id3v2_update_field(const FXchar * field,const FXStringList & value); void mp4_update_field(const FXchar * field,const FXString & value); void mp4_update_field(const FXchar * field,const FXStringList & value); void ape_update_field(const FXchar * field,const FXStringList & value); void xiph_get_field(const FXchar * field,FXString &); void xiph_get_field(const FXchar * field,FXStringList &); void id3v2_get_field(const FXchar * field,FXString &); void id3v2_get_field(const FXchar * field,FXStringList &); void mp4_get_field(const FXchar * field,FXString &); void mp4_get_field(const FXchar * field,FXStringList &); void ape_get_field(const FXchar * field,FXString &); void ape_get_field(const FXchar * field,FXStringList &); void parse_tagids(FXStringList&); public: GMFileTag(const FXString & filename); GMFileTag(TagLib::File*); void setComposer(const FXString & value); void setConductor(const FXString & value); void setAlbumArtist(const FXString & value); void setTags(const FXStringList & value); void setDiscNumber(FXushort disc); void getComposer(FXString &); void getConductor(FXString &); void getAlbumArtist(FXString &); void getTags(FXStringList&); void getTitle(FXString&); FXushort getDiscNumber(); void getGain(FXdouble & track_gain,FXdouble & track_peak,FXdouble & album_gain,FXdouble & album_peak); }; /******************************************************************************/ GMFileTag::GMFileTag(const FXString &) : file(NULL), tag(NULL), mp4(NULL), xiph(NULL), id3v2(NULL), ape(NULL) { /// TODO } GMFileTag::GMFileTag(TagLib::File * file) : file(NULL), tag(NULL), mp4(NULL), xiph(NULL), id3v2(NULL), ape(NULL) { TagLib::MPEG::File * mpgfile = NULL; TagLib::Ogg::Vorbis::File * oggfile = NULL; TagLib::FLAC::File * flacfile = NULL; #ifdef TAGLIB_HAVE_MP4 TagLib::MP4::File * mp4file = NULL; #endif tag = file->tag(); if ((oggfile = dynamic_cast(file))) { xiph=oggfile->tag(); } else if ((flacfile = dynamic_cast(file))){ xiph=flacfile->xiphComment(); id3v2=flacfile->ID3v2Tag(); } else if ((mpgfile = dynamic_cast(file))){ id3v2=mpgfile->ID3v2Tag(); ape=mpgfile->APETag(); } #ifdef TAGLIB_HAVE_MP4 else if ((mp4file = dynamic_cast(file))){ mp4=mp4file->tag(); } #endif } void GMFileTag::xiph_update_field(const FXchar * field,const FXString & value) { FXASSERT(field); FXASSERT(xiph); if (!value.empty()) xiph->addField(field,TagLib::String(value.text(),TagLib::String::UTF8),true); else xiph->removeField(field); } void GMFileTag::xiph_update_field(const FXchar * field,const FXStringList & list) { FXASSERT(field); FXASSERT(xiph); xiph->removeField(field); for (FXint i=0;iaddField(field,TagLib::String(list[i].text(),TagLib::String::UTF8),false); } } void GMFileTag::xiph_get_field(const FXchar * field,FXString & value) { FXASSERT(field); FXASSERT(xiph); if (xiph->contains(field)) value=xiph->fieldListMap()[field].front().toCString(true); else value.clear(); } void GMFileTag::xiph_get_field(const FXchar * field,FXStringList & list) { FXASSERT(field); FXASSERT(xiph); if (xiph->contains(field)) { const TagLib::StringList & fieldlist = xiph->fieldListMap()[field]; for(TagLib::StringList::ConstIterator it = fieldlist.begin(); it != fieldlist.end(); it++) { list.append(it->toCString(true)); } } else { list.clear(); } } void GMFileTag::ape_get_field(const FXchar * field,FXString & value) { FXASSERT(field); FXASSERT(ape); if (ape->itemListMap().contains(field) && !ape->itemListMap()[field].isEmpty()) value=ape->itemListMap()[field].toString().toCString(true); else value.clear(); } void GMFileTag::ape_get_field(const FXchar * field,FXStringList & list) { FXASSERT(field); FXASSERT(ape); if (ape->itemListMap().contains(field)) { TagLib::StringList fieldlist = ape->itemListMap()[field].toStringList(); for(TagLib::StringList::ConstIterator it = fieldlist.begin(); it != fieldlist.end(); it++) { list.append(it->toCString(true)); } } else { list.clear(); } } void GMFileTag::ape_update_field(const FXchar * field,const FXStringList & list) { FXASSERT(field); FXASSERT(ape); ape->removeItem(field); TagLib::StringList values; for (FXint i=0;isetItem(field,TagLib::APE::Item(field,values)); } void GMFileTag::id3v2_update_field(const FXchar * field,const FXString & value) { FXASSERT(field); FXASSERT(id3v2); if (value.empty()) { id3v2->removeFrames(field); } else if (id3v2->frameListMap().contains(field) && !id3v2->frameListMap()[field].isEmpty()) { id3v2->frameListMap()[field].front()->setText(TagLib::String(value.text(),TagLib::String::UTF8)); } else { TagLib::ID3v2::TextIdentificationFrame *frame = new TagLib::ID3v2::TextIdentificationFrame(field,TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding()); frame->setText(TagLib::String(value.text(),TagLib::String::UTF8) ); id3v2->addFrame(frame); } } void GMFileTag::id3v2_update_field(const FXchar * field,const FXStringList & list) { FXASSERT(field); FXASSERT(id3v2); if (list.no()==0) { id3v2->removeFrames(field); } else { TagLib::ID3v2::TextIdentificationFrame * frame = NULL; if (id3v2->frameListMap().contains(field) && !id3v2->frameListMap()[field].isEmpty()) { frame = dynamic_cast(id3v2->frameListMap()[field].front()); } else { frame = new TagLib::ID3v2::TextIdentificationFrame(field,TagLib::ID3v2::FrameFactory::instance()->defaultTextEncoding()); id3v2->addFrame(frame); } FXASSERT(frame); TagLib::StringList values; for (FXint i=0;isetText(values); } } void GMFileTag::id3v2_get_field(const FXchar * field,FXString & value) { FXASSERT(field); FXASSERT(id3v2); if (id3v2->frameListMap().contains(field) && !id3v2->frameListMap()[field].isEmpty() ) value=id3v2->frameListMap()[field].front()->toString().toCString(true); else value.clear(); } void GMFileTag::id3v2_get_field(const FXchar * field,FXStringList & list) { FXASSERT(field); FXASSERT(id3v2); if (id3v2->frameListMap().contains(field) && !id3v2->frameListMap()[field].isEmpty() ) { TagLib::ID3v2::TextIdentificationFrame * frame = dynamic_cast(id3v2->frameListMap()[field].front()); TagLib::StringList fieldlist = frame->fieldList(); for(TagLib::StringList::ConstIterator it = fieldlist.begin(); it != fieldlist.end(); it++) { list.append(it->toCString(true)); } } else { list.clear(); } } void GMFileTag::mp4_update_field(const FXchar * field,const FXString & value) { #ifdef TAGLIB_HAVE_MP4 FXASSERT(field); FXASSERT(mp4); if (!value.empty()) mp4->itemListMap()[field] = TagLib::StringList(TagLib::String(value.text(),TagLib::String::UTF8)); else mp4->itemListMap().erase(field); #endif } void GMFileTag::mp4_update_field(const FXchar * field,const FXStringList & list) { #ifdef TAGLIB_HAVE_MP4 FXASSERT(field); FXASSERT(mp4); if (list.no()==0) { mp4->itemListMap().erase(field); } else { TagLib::StringList values; for (FXint i=0;iitemListMap()[field]=values; } #endif } void GMFileTag::mp4_get_field(const FXchar * field,FXString & value) { #ifdef TAGLIB_HAVE_MP4 FXASSERT(field); FXASSERT(mp4); if (mp4->itemListMap().contains(field) && !mp4->itemListMap().isEmpty()) value=mp4->itemListMap()[field].toStringList().toString(", ").toCString(true); else value.clear(); #else value.clear(); #endif } void GMFileTag::mp4_get_field(const FXchar * field,FXStringList & list) { #ifdef TAGLIB_HAVE_MP4 FXASSERT(field); FXASSERT(mp4); if (mp4->itemListMap().contains(field) && !mp4->itemListMap().isEmpty()) { TagLib::StringList fieldlist = mp4->itemListMap()[field].toStringList(); for(TagLib::StringList::ConstIterator it = fieldlist.begin(); it != fieldlist.end(); it++) { list.append(it->toCString(true)); } } else list.clear(); #else list.clear(); #endif } /******************************************************************************/ void GMFileTag::setComposer(const FXString & composer) { if (xiph) xiph_update_field("COMPOSER",composer); else if (id3v2) id3v2_update_field("TCOM",composer); else if (mp4) mp4_update_field("\251wrt",composer); } void GMFileTag::getComposer(FXString & composer) { if (xiph) xiph_get_field("COMPOSER",composer); else if (id3v2) id3v2_get_field("TCOM",composer); else if (mp4) mp4_get_field("\251wrt",composer); else composer.clear(); } void GMFileTag::setConductor(const FXString & conductor) { if (xiph) xiph_update_field("COMPOSER",conductor); else if (id3v2) id3v2_update_field("TPE3",conductor); else if (mp4) mp4_update_field("----:com.apple.iTunes:CONDUCTOR",conductor); } void GMFileTag::getConductor(FXString & conductor) { if (xiph) xiph_get_field("COMPOSER",conductor); else if (id3v2) id3v2_get_field("TPE3",conductor); else if (mp4) mp4_get_field("----:com.apple.iTunes:CONDUCTOR",conductor); else conductor.clear(); } void GMFileTag::setAlbumArtist(const FXString & albumartist) { if (xiph) xiph_update_field("ALBUMARTIST",albumartist); else if (id3v2) id3v2_update_field("TPE2",albumartist); else if (mp4) mp4_update_field("aART",albumartist); } void GMFileTag::getAlbumArtist(FXString & albumartist) { if (xiph) xiph_get_field("ALBUMARTIST",albumartist); else if (id3v2) id3v2_get_field("TPE2",albumartist); else if (mp4) mp4_get_field("aART",albumartist); else albumartist.clear(); } void GMFileTag::setTags(const FXStringList & tags){ if (xiph) xiph_update_field("GENRE",tags); else if (id3v2) id3v2_update_field("TCON",tags); else if (mp4) mp4_update_field("\251gen",tags); else if (ape) ape_update_field("GENRE",tags); else { if (tags.no()) tag->setGenre(TagLib::String(tags[0].text(),TagLib::String::UTF8)); else tag->setGenre(TagLib::String("",TagLib::String::UTF8)); } } void GMFileTag::getTags(FXStringList & tags) { if (xiph) xiph_get_field("GENRE",tags); else if (id3v2) { id3v2_get_field("TCON",tags); parse_tagids(tags); } else if (mp4) mp4_get_field("\251gen",tags); else if (ape) ape_get_field("GENRE",tags); else tags.append(FXString(tag->genre().toCString(true))); } void GMFileTag::getTitle(FXString & title){ if (xiph) { FXStringList titles; xiph_get_field("TITLE",titles); title.clear(); if (titles.no()) { for (FXint i=0;ititle().toCString(true); title.trim(); } } static FXbool to_int(const FXString & str,FXint & val){ char * endptr=NULL; errno=0; val=strtol(str.text(),&endptr,10); if (errno==0) { if (endptr==str.text()) return false; return true; } return false; } void GMFileTag::parse_tagids(FXStringList & tags){ FXint id; for (FXint i=tags.no()-1;i>=0;i--){ if (to_int(tags[i],id)) { tags[i]=TagLib::ID3v1::genre(id).toCString(true); } } } void GMFileTag::setDiscNumber(FXushort disc) { if (xiph) { if (disc>0) xiph_update_field("DISCNUMBER",GMStringFormat("%d",disc)); else xiph_update_field("DISCNUMBER",FXString::null); } else if (id3v2) { if (disc>0) id3v2_update_field("TPOS",GMStringFormat("%d",disc)); else id3v2_update_field("TPOS",FXString::null); } #ifdef TAGLIB_HAVE_MP4 else if (mp4) { if (disc>0) mp4->itemListMap()["disk"] = TagLib::MP4::Item(disc,0); else mp4->itemListMap().erase("disk"); } #endif } static FXushort string_to_disc_number(const FXString & disc) { if (disc.empty()) return 0; #if FOXVERSION >= FXVERSION(1,7,12) return FXMIN(disc.before('/').toUInt(),0xFFFF); #else return FXMIN(FXUIntVal(disc.before('/')),0xFFFF); #endif } FXushort GMFileTag::getDiscNumber() { FXString disc; if (xiph) { xiph_get_field("DISCNUMBER",disc); return string_to_disc_number(disc); } else if (id3v2) { id3v2_get_field("TPOS",disc); return string_to_disc_number(disc); } #ifdef TAGLIB_HAVE_MP4 else if (mp4) { if (mp4->itemListMap().contains("disk")) return FXMIN(mp4->itemListMap()["disk"].toIntPair().first,0xFFFF); } #endif return 0; } void GMFileTag::getGain(FXdouble & track_gain,FXdouble & track_peak,FXdouble & album_gain,FXdouble & album_peak) { track_gain=track_peak=album_gain=album_peak=NAN; FXString tmp; if (xiph) { xiph_get_field("REPLAYGAIN_ALBUM_GAIN",tmp); album_gain=gm_parse_number(tmp); xiph_get_field("REPLAYGAIN_ALBUM_PEAK",tmp); album_peak=gm_parse_number(tmp); xiph_get_field("REPLAYGAIN_TRACK_GAIN",tmp); track_gain=gm_parse_number(tmp); xiph_get_field("REPLAYGAIN_TRACK_PEAK",tmp); track_peak=gm_parse_number(tmp); if (isnan(track_peak) && isnan(album_gain)) { xiph_get_field("RG_RADIO",tmp); track_gain=gm_parse_number(tmp); xiph_get_field("RG_PEAK",tmp); track_peak=gm_parse_number(tmp); xiph_get_field("RG_AUDIOPHILE",tmp); album_gain=gm_parse_number(tmp); } } else if (ape) { ape_get_field("REPLAYGAIN_ALBUM_GAIN",tmp); album_gain=gm_parse_number(tmp); ape_get_field("REPLAYGAIN_ALBUM_PEAK",tmp); album_peak=gm_parse_number(tmp); ape_get_field("REPLAYGAIN_TRACK_GAIN",tmp); track_gain=gm_parse_number(tmp); ape_get_field("REPLAYGAIN_TRACK_PEAK",tmp); track_peak=gm_parse_number(tmp); } } /******************************************************************************/ /* GMTRACK IMPLEMENTATION */ /******************************************************************************/ FXbool GMTrack::saveTag(const FXString & filename,FXuint/*opts=0*/) { if (!FXStat::isWritable(filename)) return false; TagLib::FileRef file(filename.text(),false); if (file.isNull() || !file.tag()) { return false; } TagLib::Tag * tag = file.tag(); tag->setTitle(TagLib::String(title.text(),TagLib::String::UTF8)); tag->setArtist(TagLib::String(artist.text(),TagLib::String::UTF8)); tag->setAlbum(TagLib::String(album.text(),TagLib::String::UTF8)); tag->setYear(year); tag->setTrack(getTrackNumber()); tag->setGenre(TagLib::String(genre.text(),TagLib::String::UTF8)); GMFileTag filetags(file.file()); filetags.setDiscNumber(getDiscNumber()); //filetags.setComposer(composer); //filetags.setConductor(conductor); //filetags.setTags(tags); if (album_artist!=artist && !album_artist.empty()) filetags.setAlbumArtist(album_artist); else filetags.setAlbumArtist(FXString::null); return file.save(); } FXbool GMTrack::loadTag(const FXString & filename) { FXString disc,value; TagLib::FileRef file(filename.text()); if (file.isNull() || !file.tag()) { clear(); return false; } TagLib::Tag * tag = file.tag(); TagLib::AudioProperties * properties = file.audioProperties(); mrl = filename; artist = tag->artist().toCString(true); album = tag->album().toCString(true); genre = tag->genre().toCString(true); year = tag->year(); no = FXMIN(tag->track(),0xFFFF); artist.trim(); album.trim(); if (properties) { time = properties->length(); bitrate = properties->bitrate(); } else { bitrate = 0; time = 0; } GMFileTag filetags(file.file()); filetags.getAlbumArtist(album_artist); // filetags.getComposer(composer); // filetags.getConductor(conductor); filetags.getGain(track_gain,track_peak,album_gain,album_peak); // filetags.getTags(tags); filetags.getTitle(title); if (album_artist.empty()) album_artist=artist; setDiscNumber(filetags.getDiscNumber()); // GM_DEBUG_PRINT("gain = (%lf %lf) (%lf %lf) track: %d/%d\n",album_gain,album_peak,track_gain,track_peak,getTrackNumber(),getDiscNumber()); return true; } /******************************************************************************/ /* FLAC PICTURE LOADING */ /******************************************************************************/ struct FlacPictureBlock{ FXString mimetype; FXString description; FXuint type; FXuint width; FXuint height; FXuint bps; FXuint ncolors; FXuint data_size; FXuchar* data; FXuint size() const { return 64 + description.length() + mimetype.length() + data_size; } }; #if TAGLIB_VERSION < MKVERSION(1,7,0) #if FOX_BIGENDIAN == 0 #define FLAC_LAST_BLOCK 0x80 #define FLAC_BLOCK_TYPE_MASK 0x7f #define FLAC_BLOCK_TYPE(h) (h&0x7f) #define FLAC_BLOCK_SIZE(h) ( ((h&0xFF00)<<8) | ((h&0xFF0000)>>8) | ((h&0xFF000000)>>24) ) #define FLAC_BLOCK_SET_TYPE(h,type) (h|=(type&FLAC_BLOCK_TYPE_MASK)) #define FLAC_BLOCK_SET_SIZE(h,size) (h|=(((size&0xFF)<<24) | ((size&0xFF0000)>>16) | ((size&0xFF00)<<8))) #else #define FLAC_LAST_BLOCK 0x80000000 #define FLAC_BLOCK_TYPE_MASK 0x7F000000 #define FLAC_BLOCK_TYPE(h) ((h&0x7F000000)>>24) #define FLAC_BLOCK_SIZE(h) (h&0xFFFFFF) #define FLAC_BLOCK_SET_TYPE(h,type) (h|=((type<<24)&FLAC_BLOCK_TYPE_MASK)) #define FLAC_BLOCK_SET_SIZE(h,size) (h|=(size&0xFFFFFF)) #endif enum { FLAC_BLOCK_STREAMINFO = 0, FLAC_BLOCK_PADDING = 1, FLAC_BLOCK_VORBIS_COMMENT = 4, FLAC_BLOCK_PICTURE = 6 }; static FXbool gm_read_uint32_be(FXIO & io,FXuint & v) { #if FOX_BIGENDIAN == 0 FXuchar block[4]; if (io.readBlock(block,4)!=4) return false; ((FXuchar*)&v)[3]=block[0]; ((FXuchar*)&v)[2]=block[1]; ((FXuchar*)&v)[1]=block[2]; ((FXuchar*)&v)[0]=block[3]; #else if (io.readBlock(&v,4)!=4) return false; #endif return true; } static FXbool gm_read_string_be(FXIO & io,FXString & v) { FXuint len=0; gm_read_uint32_be(io,len); if (len>0) { v.length(len); if (io.readBlock(&v[0],len)!=len) return false; } return true; } FXbool gm_flac_is_front_cover(FXIO & io) { FlacPictureBlock picture; gm_read_uint32_be(io,picture.type); if (picture.type==GMCover::FrontCover) return true; else return false; } GMCover * gm_flac_parse_block_picture(FXIO & io,FXint scale) { GMCover* cover=NULL; FlacPictureBlock picture; gm_read_uint32_be(io,picture.type); /// Skip useless icons if (picture.type==GMCover::FileIcon || picture.type==GMCover::OtherFileIcon || picture.type==GMCover::Fish) { return NULL; } gm_read_string_be(io,picture.mimetype); gm_read_string_be(io,picture.description); gm_read_uint32_be(io,picture.width); gm_read_uint32_be(io,picture.height); gm_read_uint32_be(io,picture.bps); gm_read_uint32_be(io,picture.ncolors); gm_read_uint32_be(io,picture.data_size); if (picture.data_size>0) { allocElms(picture.data,picture.data_size); if (io.readBlock(picture.data,picture.data_size)==picture.data_size) { FXImage * image = gm_load_image_from_data(picture.data,picture.data_size,picture.mimetype,scale); if (image) { cover = new GMCover(image,picture.type,picture.description); } } freeElms(picture.data); } return cover; } static FXbool gm_flac_parse_header(FXIO & io,FXuint & header) { FXchar marker[4]; if (io.readBlock(marker,4)!=4 || compare(marker,"fLaC",4)) return false; if (io.readBlock(&header,4)!=4 || FLAC_BLOCK_TYPE(header)!=FLAC_BLOCK_STREAMINFO || FLAC_BLOCK_SIZE(header)!=34 || (header&FLAC_LAST_BLOCK)) return false; /// Go to beginning of meta data io.position(34,FXIO::Current); return true; } static FXbool gm_flac_next_block(FXIO & io,FXuint & header) { if (!(header&FLAC_LAST_BLOCK) && (io.readBlock(&header,4)==4)) return true; else return false; } static FXint flac_load_covers(const FXString & mrl,GMCoverList & covers,FXint scale) { FXuint header; FXFile io; if (io.open(mrl,FXIO::Reading)) { if (!gm_flac_parse_header(io,header)) return 0; while(gm_flac_next_block(io,header)) { if (FLAC_BLOCK_TYPE(header)==FLAC_BLOCK_PICTURE) { GMCover * cover = gm_flac_parse_block_picture(io,scale); if (cover) covers.append(cover); } else if (!(header&FLAC_LAST_BLOCK)){ io.position(FLAC_BLOCK_SIZE(header),FXIO::Current); } } } return covers.no(); } static GMCover * flac_load_cover(const FXString & mrl,FXint scale) { FXuint header; FXlong pos; FXFile io; if (io.open(mrl,FXIO::Reading)) { if (!gm_flac_parse_header(io,header)) return 0; while(gm_flac_next_block(io,header)) { if (FLAC_BLOCK_TYPE(header)==FLAC_BLOCK_PICTURE) { pos=io.position(); if (gm_flac_is_front_cover(io)) { io.position(pos,FXIO::Begin); GMCover * cover = gm_flac_parse_block_picture(io,scale); if (cover) return cover; } } else if (!(header&FLAC_LAST_BLOCK)){ io.position(FLAC_BLOCK_SIZE(header),FXIO::Current); } } } return NULL; } #endif static FXbool gm_uint32_be(const FXuchar * block,FXuint & v) { #if FOX_BIGENDIAN == 0 ((FXuchar*)&v)[3]=block[0]; ((FXuchar*)&v)[2]=block[1]; ((FXuchar*)&v)[1]=block[2]; ((FXuchar*)&v)[0]=block[3]; #else ((FXuchar*)&v)[3]=block[3]; ((FXuchar*)&v)[2]=block[2]; ((FXuchar*)&v)[1]=block[1]; ((FXuchar*)&v)[0]=block[0]; #endif return true; } static GMCover * gm_flac_parse_block_picture(const FXuchar * buffer,FXint len,FXint scale) { FlacPictureBlock picture; const FXuchar * p = buffer; FXuint sz; gm_uint32_be(p,picture.type); /// Skip useless icons if (picture.type==GMCover::FileIcon || picture.type==GMCover::OtherFileIcon || picture.type==GMCover::Fish) { return NULL; } p+=4; gm_uint32_be(p,sz); picture.mimetype.length(sz); picture.mimetype.assign((const FXchar*)p+4,sz); p+=(4+sz); gm_uint32_be(p,sz); picture.description.length(sz); picture.description.assign((const FXchar*)p+4,sz); p+=(4+sz); gm_uint32_be(p+0,picture.width); gm_uint32_be(p+4,picture.height); gm_uint32_be(p+8,picture.bps); gm_uint32_be(p+12,picture.ncolors); gm_uint32_be(p+16,picture.data_size); if (picture.data_size>0) { picture.data = (FXuchar*) p+20; if (picture.data+picture.data_size>buffer+len) return NULL; FXImage * image = gm_load_image_from_data(picture.data,picture.data_size,picture.mimetype,scale); if (image) return new GMCover(image,picture.type,picture.description); } return NULL; } static GMCover * xiph_load_cover(const TagLib::ByteVector & tbuf,FXint scale) { GMCover * cover = NULL; if (tbuf.size()) { FXuchar * buffer=NULL; FXint len=tbuf.size(); allocElms(buffer,len); memcpy(buffer,tbuf.data(),len); if (gm_decode_base64(buffer,len)) { cover = gm_flac_parse_block_picture(buffer,len,scale); } freeElms(buffer); } return cover; } namespace GMTag { void init(){ TagLib::ID3v2::FrameFactory::instance()->setDefaultTextEncoding(TagLib::String::UTF16); } FXbool length(GMTrack & info) { TagLib::FileRef file(info.mrl.text()); if (file.isNull()) return false; TagLib::AudioProperties *prop = file.audioProperties(); if (prop) info.time = prop->length(); else info.time = 0; return true; } FXbool properties(const FXString & mrl,Properties & p) { p.bitrate=-1; p.samplerate=-1; p.channels=-1; TagLib::FileRef file(mrl.text()); if (file.isNull()) return false; TagLib::AudioProperties *prop = file.audioProperties(); if (!prop) return false; p.bitrate = prop->bitrate(); p.samplerate = prop->sampleRate(); p.channels = prop->channels(); return true; } } GMCover::GMCover() : image(NULL), type(0) { } GMCover::GMCover(FXImage * img,FXuint t,const FXString & label) : image(img),description(label),type(t) { } GMCover::~GMCover() { if (image) { delete image; image=NULL; } } #if TAGLIB_VERSION >= MKVERSION(1,7,0) GMCover* flac_load_cover_from_taglib(const TagLib::FLAC::Picture * picture,FXint scale) { GMCover * cover=NULL; if (picture) { if (picture->type()==TagLib::FLAC::Picture::FileIcon || picture->type()==TagLib::FLAC::Picture::OtherFileIcon || picture->type()==TagLib::FLAC::Picture::ColouredFish) { return NULL; } FXImage * image = gm_load_image_from_data(picture->data().data(),picture->data().size(),picture->mimeType().toCString(true),scale); if (image) { cover = new GMCover(image,picture->type(),picture->description().toCString(true)); } } return cover; } GMCover* flac_load_frontcover_from_taglib(const TagLib::FLAC::Picture * picture,FXint scale) { GMCover * cover=NULL; if (picture && picture->type()==TagLib::FLAC::Picture::FrontCover) { FXImage * image = gm_load_image_from_data(picture->data().data(),picture->data().size(),picture->mimeType().toCString(true),scale); if (image) { cover = new GMCover(image,picture->type(),picture->description().toCString(true)); } } return cover; } #endif FXint GMCover::fromTag(const FXString & mrl,GMCoverList & covers,FXint scale/*=0*/) { FXString extension = FXPath::extension(mrl); #if TAGLIB_VERSION < MKVERSION(1,7,0) if (comparecase(extension,"flac")==0){ flac_load_covers(mrl,covers,scale); if (covers.no()) return (covers.no()); } #endif TagLib::FileRef file(mrl.text(),false); if (file.isNull() || !file.tag()) { return 0; } #if TAGLIB_VERSION >= MKVERSION(1,7,0) TagLib::FLAC::File * flacfile = dynamic_cast(file.file()); if (flacfile) { const TagLib::List picturelist = flacfile->pictureList(); for(TagLib::List::ConstIterator it = picturelist.begin(); it != picturelist.end(); it++) { GMCover * cover = flac_load_cover_from_taglib((*it),scale); if (cover) covers.append(cover); } if (covers.no()) { return (covers.no()); } } #endif GMFileTag tags(file.file()); FXIconSource src(FXApp::instance()); if (tags.xiph) { if (tags.xiph->contains("METADATA_BLOCK_PICTURE")) { const TagLib::StringList & coverlist = tags.xiph->fieldListMap()["METADATA_BLOCK_PICTURE"]; for(TagLib::StringList::ConstIterator it = coverlist.begin(); it != coverlist.end(); it++) { GMCover * cover = xiph_load_cover((*it).data(TagLib::String::UTF8),scale); if (cover) covers.append(cover); } } } if (tags.id3v2) { TagLib::ID3v2::FrameList framelist = tags.id3v2->frameListMap()["APIC"]; if(!framelist.isEmpty()){ for(TagLib::ID3v2::FrameList::Iterator it = framelist.begin(); it != framelist.end(); it++) { TagLib::ID3v2::AttachedPictureFrame * frame = dynamic_cast(*it); GMCover * cover = id3v2_load_cover(frame,scale); if (cover) covers.append(cover); } } } #ifdef TAGLIB_HAVE_MP4 else if (tags.mp4) { if (tags.mp4->itemListMap().contains("covr")) { TagLib::MP4::CoverArtList coverlist = tags.mp4->itemListMap()["covr"].toCoverArtList(); for(TagLib::MP4::CoverArtList::Iterator it = coverlist.begin(); it != coverlist.end(); it++) { FXImage * img = NULL; if (it->format()==TagLib::MP4::CoverArt::PNG) img = gm_load_image_from_data(it->data().data(),it->data().size(),FXPNGImage::fileExt,scale); else if (it->format()==TagLib::MP4::CoverArt::JPEG) img = gm_load_image_from_data(it->data().data(),it->data().size(),FXJPGImage::fileExt,scale); if (img) covers.append(new GMCover(img,0)); } } } #endif return covers.no(); } FXint GMCover::fromPath(const FXString & path,GMCoverList & list,FXint scale/*=0*/) { FXString * files=NULL; FXImage * image; FXIconSource src(FXApp::instance()); FXint nfiles = FXDir::listFiles(files,path,"*.(png,jpg,jpeg,bmp,gif)",FXDir::NoDirs|FXDir::NoParent|FXDir::CaseFold|FXDir::HiddenFiles); if (nfiles) { for (FXint i=0;i= MKVERSION(1,7,0) TagLib::FLAC::File * flacfile = dynamic_cast(file.file()); if (flacfile) { const TagLib::List picturelist = flacfile->pictureList(); for(TagLib::List::ConstIterator it = picturelist.begin(); it != picturelist.end(); it++) { GMCover * cover = flac_load_frontcover_from_taglib((*it),scale); if (cover) { return cover;} } } #endif if (tags.id3v2) { TagLib::ID3v2::FrameList framelist = tags.id3v2->frameListMap()["APIC"]; if(!framelist.isEmpty()){ /// First Try Front Cover for(TagLib::ID3v2::FrameList::Iterator it = framelist.begin(); it != framelist.end(); it++) { TagLib::ID3v2::AttachedPictureFrame * frame = dynamic_cast(*it); FXASSERT(frame); if (id3v2_is_front_cover(frame)) { GMCover * cover = id3v2_load_cover(frame,scale); if (cover) { return cover;} } } for(TagLib::ID3v2::FrameList::Iterator it = framelist.begin(); it != framelist.end(); it++) { TagLib::ID3v2::AttachedPictureFrame * frame = dynamic_cast(*it); FXASSERT(frame); GMCover * cover = id3v2_load_cover(frame,scale); if (cover) { return cover;} } } } else if (tags.xiph) { if (tags.xiph->contains("METADATA_BLOCK_PICTURE")) { const TagLib::StringList & coverlist = tags.xiph->fieldListMap()["METADATA_BLOCK_PICTURE"]; for(TagLib::StringList::ConstIterator it = coverlist.begin(); it != coverlist.end(); it++) { GMCover * cover = xiph_load_cover((*it).data(TagLib::String::UTF8),scale); if (cover) { return cover;} } } } #ifdef TAGLIB_HAVE_MP4 if (tags.mp4) { /// MP4 if (tags.mp4->itemListMap().contains("covr")) { TagLib::MP4::CoverArtList coverlist = tags.mp4->itemListMap()["covr"].toCoverArtList(); for(TagLib::MP4::CoverArtList::Iterator it = coverlist.begin(); it != coverlist.end(); it++) { FXImage * img = NULL; if (it->format()==TagLib::MP4::CoverArt::PNG) img = gm_load_image_from_data(it->data().data(),it->data().size(),FXPNGImage::fileExt,scale); else if (it->format()==TagLib::MP4::CoverArt::JPEG) img = gm_load_image_from_data(it->data().data(),it->data().size(),FXJPGImage::fileExt,scale); if (img) { return new GMCover(img,0); } } } } #endif return NULL; } GMCover * GMCover::fromPath(const FXString & path,FXint scale/*=0*/) { static const FXchar * covernames[]={"cover","album","front","albumart",".folder","folder",NULL}; FXString * files=NULL; FXString * names=NULL; FXImage * image=NULL; FXIconSource src(FXApp::instance()); FXint nfiles = FXDir::listFiles(files,path,"*.(png,jpg,jpeg,bmp,gif)",FXDir::NoDirs|FXDir::NoParent|FXDir::CaseFold|FXDir::HiddenFiles); if (nfiles) { names = new FXString[nfiles]; for (FXint i=0;iimage; cover->image=NULL; delete cover; return image; } return NULL; } FXIcon * GMCover::toIcon(GMCover * cover) { if (cover) { FXImage * image = GMCover::toImage(cover); if (image) { FXIcon * icon = new FXIcon(FXApp::instance(),image->getData(),0,IMAGE_OWNED,image->getWidth(),image->getHeight()); FXImageOwner::clear(image); delete image; return icon; } } return NULL; } GMTrack::GMTrack() : year(0), no(0), time(0), bitrate(0), album_gain(NAN), album_peak(NAN), track_gain(NAN), track_peak(NAN){ } void GMTrack::clear() { path.clear(); title.clear(); artist.clear(); album.clear(); album_artist.clear(); genre.clear(); year=0; no=0; time=0; bitrate=0; album_gain=NAN; album_peak=NAN; track_gain=NAN; track_peak=NAN; } gogglesmm-0.12.7/src/ap_http.h0000644000175000001440000001715112063215477014720 0ustar sxjusers#ifndef AP_HTTP_H #define AP_HTTP_H #ifndef GMAPI #define GMAPI #endif namespace ap { enum { // HTTP status types HTTP_RESPONSE_FAILED = 0, HTTP_RESPONSE_INFORMATIONAL = 1, HTTP_RESPONSE_SUCCESS = 2, HTTP_RESPONSE_REDIRECT = 3, HTTP_RESPONSE_CLIENT_ERROR = 4, HTTP_RESPONSE_SERVER_ERROR = 5, // Informational 1xx HTTP_CONTINUE = 100, HTTP_SWITCHING_PROTOCOLS = 101, HTTP_PROCESSING = 102, // RFC2518 - WebDAV // Succesful 2xx HTTP_OK = 200, HTTP_CREATED = 201, HTTP_ACCEPTED = 202, HTTP_NONAUTHORITATIVE_INFORMATION = 203, HTTP_NO_CONTENT = 204, HTTP_RESET_CONTENT = 205, HTTP_PARTIAL_CONTENT = 206, HTTP_MULTI_STATUS = 207, //WEBDAV HTTP_IM_USED = 226, //RFC3229 // Redirect 3xx HTTP_MULTIPLE_CHOICES = 300, HTTP_MOVED_PERMANENTLY = 301, HTTP_FOUND = 302, HTTP_SEE_OTHER = 303, HTTP_NOT_MODIFIED = 304, HTTP_USE_PROXY = 305, HTTP_TEMPORARY_REDIRECT = 307, // Client Error 4xx HTTP_BADREQUEST = 400, HTTP_UNAUTHORIZED = 401, HTTP_PAYMENTREQUIRED = 402, HTTP_FORBIDDEN = 403, HTTP_NOT_FOUND = 404, HTTP_METHOD_NOT_ALLOWED = 405, HTTP_NOT_ACCEPTABLE = 406, HTTP_PROXY_AUTHENTICATION_REQUIRED = 407, HTTP_REQUEST_TIMEOUT = 408, HTTP_CONFLICT = 409, HTTP_GONE = 410, HTTP_LENGTH_REQUIRED = 411, HTTP_PRECONDITION_FAILED = 412, HTTP_REQUESTENTITY_TOO_LARGE = 413, HTTP_REQUESTURI_TOO_LONG = 414, HTTP_UNSUPPORTED_MEDIATYPE = 415, HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416, HTTP_EXPECTATION_FAILED = 417, HTTP_UNPROCESSABLE_ENTITY = 422, HTTP_LOCKED = 423, HTTP_FAILED_DEPENDENCY = 424, //RFC4918 - WEBDAV HTTP_NO_CODE = 425, HTTP_UPGRADE_REQUIRED = 426, // Server Error 5xx HTTP_INTERNAL_SERVER_ERROR = 500, HTTP_NOT_IMPLEMENTED = 501, HTTP_BAD_GATEWAY = 502, HTTP_SERVICE_UNAVAILABLE = 503, HTTP_GATEWAY_TIMEOUT = 504, HTTP_VERSION_NOTSUPPORTED = 505, HTTP_INSUFFICIENT_STORAGE = 507, //RFC4918 - WEBDAV HTTP_BANDWITH_LIMIT_EXCEEDED = 509, HTTP_NOT_EXTENDED = 510 //RFC 2774 }; enum { HEADER_MULTIPLE_LINES = 0, HEADER_SINGLE_LINE = 1 }; /* Http Status */ struct GMAPI HttpStatus { FXint major; FXint minor; FXint code; FXint type() const; }; /* Http Response Parser */ class GMAPI HttpResponse { private: MemoryBuffer buffer; // Internal Buffer protected: FXuint flags; // Options flags used by parser FXint content_length; // Content Length from header FXint content_remaining; // Content left to read FXint chunk_remaining; // Remaining bytes left to read in chunk public: HttpStatus status; // Response Status. Valid after response() returns true FXDict headers; // Dictionary of all http headers protected: // Internal Parser Flags enum { ChunkedResponse = 0x1, // Chunked Response ConnectionClose = 0x2, // Connection Closes ResponseComplete = 0x4, HeadRequest = 0x8, Last = 0x10 }; protected: /// read nbytes from source. virtual FXival readBlock(void * ptr,FXival nbytes)=0; private: /// read nbytes FXival read(FXchar*ptr,FXival nbytes); /// read (at most) nbytes into buffer FXival fill(FXival nbytes=128); private: // Try reading complete header from buffer FXbool parse_header(FXString & header,FXuint span); // Add header to dictionary void insert_header(const FXString &); // Check all headers we're interested in void check_headers(); // Clear Headers void clear_headers(); private: // Reads chunk header and gives back size. FXbool read_chunk_header(FXint & chunksize); // Read regular FXbool read_header(FXString & header,FXuint span); // Read status line FXbool read_status(); private: // Read body using normal transfer. Returns a string FXString read_body(); // Read body using chunked transfer. Returns a string FXString read_body_chunked(); // Read body using normal transfer. Returns size of message body or -1. FXival read_body(FXchar*&); // Read body using chunked transfer. Returns size of message body or -1. FXival read_body_chunked(FXchar*&); // Read body using chunked transfer FXival read_body_chunked(void * ptr,FXival len); // Read body using normal transfer FXival read_body(void * ptr,FXival len); protected: // Constructor HttpResponse(); // Clear Response void clear(); public: // Completes reading response virtual void discard(); // Read response status and headers. FXint parse(); // Return the complete message body as string FXString body(); // Return the complete message body as buffer. Returns body size or -1 on error. // Buffer needs to be freed with freeElms() FXival body(FXchar *& out); /// Read partial body FXival readBody(void*ptr,FXival len); // Return header for given key FXString getHeader(const FXString & key) const; // Return Content Length if known or -1 FXint getContentLength() const; // Destructor virtual ~HttpResponse(); }; struct HttpHost { FXString name; FXint port; HttpHost(); HttpHost(const FXString & url); // Set from url. returns true if changed FXbool set(const FXString & url); // Clear void clear(); }; class GMAPI HttpClient : public HttpResponse { protected: FXInputHandle device; protected: HttpHost server; HttpHost proxy; protected: enum { UseProxy = 0x10, // Keep in Sync with HttpResponse UseNonBlock = 0x20, // Non Blocking Sockets }; protected: virtual FXival readBlock(void*,FXival); virtual FXival writeBlock(const void*,FXival); // Subclass for non-blocking IO virtual FXbool wait_write(FXInputHandle) { return false; } protected: FXbool send(const FXchar *,FXint len); FXbool open_connection(); // Reset Response void reset(FXbool forceclose); public: HttpClient(); void close(); // Discard response virtual void discard(); FXbool request(const FXchar * method,const FXString & url,const FXString & headers=FXString::null,const FXString & message=FXString::null); // Perform basic request and handles some basic HTTP features FXbool basic(const FXchar * method, FXString url, const FXString & headers=FXString::null, const FXString & body=FXString::null); ~HttpClient(); }; } #endif gogglesmm-0.12.7/src/GMWindow.h0000644000175000001440000002021211525430601014732 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMWINDOW_H #define GMWINDOW_H class GMRemote; class GMTrackView; class GMSourceView; class GMIconTheme; class GMPreferencesDialog; class GMImageView; class GMCoverFrame; enum { DISPLAYMODE_UNDEFINED=-1, DISPLAYMODE_NORMAL=0, DISPLAYMODE_LIST=1, }; enum { SHOW_NORMAL, SHOW_WIZARD, SHOW_TRAY }; class GMWindow : public FXMainWindow { FXDECLARE(GMWindow) friend class GMRemote; friend class GMPlayerManager; friend class GMTrackView; friend class GMPreferencesDialog; private: FXMenuPtr filemenu; FXMenuPtr editmenu; FXMenuPtr viewmenu; FXMenuPtr playmenu; FXMenuPtr helpmenu; FXMenuButton *volumebutton; FXPopup *volumecontrol; FXSlider *volumeslider; private: GMIconTheme * icontheme; GMTrackView * trackview; GMSourceView * sourceview; FXHorizontalFrame * controlframe; FXHorizontalFrame * statusframe; GMCoverFrame * coverframe; GMImageView * coverview_gl; FXImageFrame * coverview_x11; FXGLVisual * glvisual; FXToggleButton * playpausebutton; FXButton * stopbutton; FXButton * nextbutton; FXButton * prevbutton; #if FOXVERSION > FXVERSION(1,7,11) FXMenuCheck * fullscreencheck; #endif FXSeparator * controlseparator; FXDragCorner * controldragcorner; FXSeparator * controlstatusseparator; FX7Segment * timelabel; FXSlider * timeslider; #if FOXVERSION > FXVERSION(1,7,21) FX4Splitter * mainsplitter; #else FXSplitter * mainsplitter; FXSplitter * sourcesplitter; #endif FXStatusBar * statusbar; FXTextField * nowplaying; GMRemote * remote; private: FXString coverfile; private: FXFontPtr font_thick; FXImagePtr cover_small; private: void createFonts(); void configureToolbar(FXbool docktop,FXbool showlabels,FXbool bigicons,FXbool init=false); void configureStatusbar(FXbool show); #if FOXVERSION > FXVERSION(1,7,11) void setFullScreen(FXbool show); #endif private: GMWindow(){} GMWindow(const GMWindow&); GMWindow& operator=(const GMWindow&); public: /// Message Handlers long onCmdAbout(FXObject*,FXSelector,void*); long onCmdQuit(FXObject*,FXSelector,void*); long onCmdPreferences(FXObject*,FXSelector,void*); long onCmdTimeSlider(FXObject*,FXSelector,void*); long onCmdVolume(FXObject*,FXSelector,void*); long onCmdVolumeButton(FXObject*,FXSelector,void*); long onUpdVolumeButton(FXObject*,FXSelector,void*); long onCmdOpen(FXObject*,FXSelector,void*); long onCmdImport(FXObject*,FXSelector,void*); long onCmdImportFiles(FXObject*,FXSelector,void*); long onCmdShowTrack(FXObject*,FXSelector,void*); long onUpdShowTrack(FXObject*,FXSelector,void*); #if FOXVERSION >= FXVERSION(1,7,11) long onCmdShowFullScreen(FXObject*,FXSelector,void*); #endif #if FOXVERSION > FXVERSION(1,7,21) long onCmdShowSources(FXObject*,FXSelector,void*); long onUpdShowSources(FXObject*,FXSelector,void*); #endif long onCmdShowMiniPlayer(FXObject*,FXSelector,void*); long onUpdShowMiniPlayer(FXObject*,FXSelector,void*); long onCmdPlayPause(FXObject*,FXSelector,void*); long onUpdPlayPause(FXObject*,FXSelector,void*); long onCmdPlayPauseMenu(FXObject*,FXSelector,void*); long onUpdPlayPauseMenu(FXObject*,FXSelector,void*); long onCmdPause(FXObject*,FXSelector,void*); long onUpdPause(FXObject*,FXSelector,void*); long onCmdStop(FXObject*,FXSelector,void*); long onUpdStop(FXObject*,FXSelector,void*); long onCmdNext(FXObject*,FXSelector,void*); long onUpdNext(FXObject*,FXSelector,void*); long onCmdPrev(FXObject*,FXSelector,void*); long onUpdPrev(FXObject*,FXSelector,void*); long onCmdRepeatAll(FXObject*,FXSelector,void*); long onUpdRepeatAll(FXObject*,FXSelector,void*); long onCmdRepeatAB(FXObject*,FXSelector,void*); long onUpdRepeatAB(FXObject*,FXSelector,void*); long onCmdRepeatOff(FXObject*,FXSelector,void*); long onUpdRepeatOff(FXObject*,FXSelector,void*); long onCmdRepeat(FXObject*,FXSelector,void*); long onUpdRepeat(FXObject*,FXSelector,void*); long onCmdSleepTimer(FXObject*,FXSelector,void*); long onUpdSleepTimer(FXObject*,FXSelector,void*); long onCmdShuffle(FXObject*,FXSelector,void*); long onUpdShuffle(FXObject*,FXSelector,void*); long onCmdHomePage(FXObject*,FXSelector,void*); long onCmdReportIssue(FXObject*,FXSelector,void*); long onCmdJoinLastFM(FXObject*,FXSelector,void*); long onCmdJoinGMMLastFM(FXObject*,FXSelector,void*); long onCmdResetColors(FXObject*,FXSelector,void*); long onCmdChangeCoverView(FXObject*,FXSelector,void*); long onCmdCoverView(FXObject*,FXSelector,void*); long onCmdCoverSize(FXObject*,FXSelector,void*); long onUpdCoverSize(FXObject*,FXSelector,void*); public: enum{ ID_ABOUT=FXMainWindow::ID_LAST, ID_QUIT, ID_OPEN, ID_HOMEPAGE, ID_REPORT_ISSUE, ID_JOIN_LASTFM, ID_JOIN_GMM_LASTFM, ID_PAUSE, ID_PLAYPAUSE, ID_PLAYPAUSEMENU, ID_STOP, ID_NEXT, ID_PREV, ID_REPEAT, ID_REPEAT_ALL, ID_REPEAT_AB, ID_REPEAT_OFF, ID_SHUFFLE, ID_TIMESLIDER, ID_VOLUME_BUTTON, ID_VOLUME_SLIDER, ID_DISPLAYMODE, ID_DATABASE_CLEAR, ID_IMPORT_DIRS, ID_IMPORT_FILES, ID_SYNC_DIRS, ID_PREFERENCES, ID_SHOW_TRACK, #if FOXVERSION >= FXVERSION(1,7,11) ID_SHOW_FULLSCREEN, ID_SHOW_SOURCES, #endif ID_SHOW_MINIPLAYER, ID_OPEN_DIR, ID_RESET_COLORS, ID_DDE_MESSAGE, ID_SLEEP, ID_COVERVIEW, ID_CHANGE_COVERVIEW, ID_COVERSIZE_SMALL, ID_COVERSIZE_MEDIUM, ID_COVERSIZE_LARGE, ID_COVERSIZE_EXTRALARGE, ID_LAST }; public: GMWindow(FXApp* a,FXObject*tgt,FXSelector sel); void showRemote(); void hideRemote(); GMRemote * getRemote() const { return remote; } void updateCoverView(); void create_dialog_header(FXDialogBox * dialog,const FXString & title,const FXString & label,FXIcon * icon=NULL); FXbool question(const FXString & title,const FXString & label,const FXString & accept,const FXString & cancel); void reset(); void display(const GMTrack&); void init(FXuint); void toggleShown(); /// Create window virtual void create(); virtual void show(); virtual void hide(); GMTrackView * getTrackView() const { return trackview; } GMSourceView * getSourceView() const {return sourceview;} void loadCover(const FXString & filename); void update_elapsed_time(FXint hours,FXint minutes,FXint seconds,FXint position,FXbool playing,FXbool seekable); void update_volume_display(FXint level); FXFont * getThickFont() const { return font_thick; } FXImage * getSmallCover() const { return cover_small; } void layoutToolBarButtons(); /// Destructor virtual ~GMWindow(); }; #endif gogglesmm-0.12.7/src/GMIconTheme.cpp0000644000175000001440000005135511646153742015721 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "gmutils.h" #include "GMIconTheme.h" #include "GMApp.h" #include "GMPlayerManager.h" #include "GMPreferences.h" #include "icons.h" #include #include #include #include #define SMALL_SIZE 16 #define MEDIUM_SIZE 22 #define LARGE_SIZE 48 void GMIconSet::save(FXStream & store) { store << name; store << dir; store << small; store << medium; store << large; } void GMIconSet::load(FXStream & store) { store >> name; store >> dir; store >> small; store >> medium; store >> large; } void gm_set_application_icon(FXWindow * window) { FXPNGImage * image = new FXPNGImage(FXApp::instance(),gogglesmm_32_png,0,0); ewmh_set_window_icon(window,image); delete image; } static const FXuint CACHE_FILE_VERSION = 20101108; static const FXchar CACHE_FILE_NAME[] = PATHSEPSTRING "icontheme.cache"; static const FXchar CACHE_SVG_NAME[] = PATHSEPSTRING "svg"; void GMIconTheme::save_cache() { const FXuint cache_file_version = CACHE_FILE_VERSION; FXString dirs; for (FXint i=0;itheme_dir_date) theme_dir_date=tm; } /// Any dirs newer, then reload. if (theme_dir_date==0 || cache_dir_date==0 || theme_dir_date>cache_dir_date) return false; FXFileStream store; if (store.open(GMApp::getCacheDirectory()+PATHSEPSTRING+"icontheme.cache",FXStreamLoad)) { store >> cache_file_version; if (cache_file_version!=CACHE_FILE_VERSION) { return false; } for (FXint i=0;i> cache_dirs; if (dirs!=cache_dirs) return false; store >> cache_size; if (cache_size!=smallsize) return false; store >> cache_size; if (cache_size!=mediumsize) return false; store >> cache_size; if (cache_size!=largesize) return false; store >> n; iconsets.no(n); for (FXint i=0;ireg().readIntEntry("user-interface","icon-theme-small-size",SMALL_SIZE); mediumsize = app->reg().readIntEntry("user-interface","icon-theme-medium-size",MEDIUM_SIZE); largesize = app->reg().readIntEntry("user-interface","icon-theme-large-size",LARGE_SIZE); if (!FXPath::search(FXSystem::getEnvironment("PATH"),"rsvg-convert").empty()){ rsvg=true; } init_basedirs(basedirs); if (!load_cache()) { clear_svg_cache(); build(); save_cache(); } const FXchar * theme = app->reg().readStringEntry("user-interface","icon-theme","Tango"); if (theme) { for (FXint i=0;icreate(); } GMIconTheme::~GMIconTheme() { } GMIconTheme * GMIconTheme::instance(){ return me; } static void init_themedict(FXStringList & basedirs,FXStringDict & themedict){ FXString * dirs=NULL; for (FXint i=0;i=0;) { themedirs = index[xx].readStringEntry("Icon Theme","Directories",NULL); parents = index[xx].readStringEntry("Icon Theme","Inherits","hicolor"); inherits[x].insert(base.text(),(void*)(FXival)1); for (s=0;;s++) { dir = themedirs.section(',',s); if (dir.empty()) break; const FXchar * type = index[xx].readStringEntry(dir.text(),"Type","Threshold"); const FXint size = index[xx].readIntEntry(dir.text(),"Size",0); const FXint threshold = index[xx].readIntEntry(dir.text(),"Threshold",2); const FXint minsize = index[xx].readIntEntry(dir.text(),"MinSize",size); const FXint maxsize = index[xx].readIntEntry(dir.text(),"MaxSize",size); if (comparecase(type,"scalable")==0) { if (smallsize>=minsize && smallsize<=maxsize) add_path(basedirs,base,dir,smallpath); if (mediumsize>=minsize && mediumsize<=maxsize) add_path(basedirs,base,dir,mediumpath); if (largesize>=minsize && largesize<=maxsize) add_path(basedirs,base,dir,largepath); } else if (comparecase(type,"fixed")==0) { if (size==smallsize) add_path(basedirs,base,dir,smallpath); else if (size==mediumsize) add_path(basedirs,base,dir,mediumpath); else if (size==largesize) add_path(basedirs,base,dir,largepath); } else { if (FXABS(smallsize-size)<=threshold) add_path(basedirs,base,dir,smallpath); else if (FXABS(mediumsize-size)<=threshold) add_path(basedirs,base,dir,mediumpath); else if (FXABS(largesize-size)<=threshold) add_path(basedirs,base,dir,largepath); } } /// Find next inherited for (s=0,xx=-1;xx==-1;s++) { base = parents.section(',',s); if (base.empty() || inherits[x].find(base.text())) break; xx = (FXint)(FXival)indexmap.find(base.text()) - 1; } } if (smallpath.empty() && mediumpath.empty() && largepath.empty()) continue; /// Finally add the theme const FXint current=iconsets.no(); iconsets.no(current+1); iconsets[current].name = index[x].readStringEntry("Icon Theme","Name",themedir); iconsets[current].dir = themedir; iconsets[current].small.adopt(smallpath); iconsets[current].medium.adopt(mediumpath); iconsets[current].large.adopt(largepath); } delete [] index; delete [] inherits; } } FXImage * GMIconTheme::loadImage(const FXString & filename) { FXImage * img=NULL; const FXString ext = FXPath::extension(filename); FXFileStream store; if(store.open(filename,FXStreamLoad,65536)){ if(comparecase(FXPNGImage::fileExt,ext)==0){ img=new FXPNGImage(app); } else if(comparecase(FXJPGImage::fileExt,ext)==0 || comparecase("jpeg",ext)==0){ img=new FXJPGImage(app); } else if(comparecase(FXBMPIcon::fileExt,ext)==0){ img=new FXBMPImage(app); } else if(comparecase(FXGIFIcon::fileExt,ext)==0){ img=new FXGIFImage(app); } else { img=NULL; } if(img){ if(img->loadPixels(store)) return img; delete img; img=NULL; } } return NULL; } FXIcon * GMIconTheme::loadIcon(const FXString & filename) { FXIcon * icon=NULL; const FXString ext = FXPath::extension(filename); FXFileStream store; if(store.open(filename,FXStreamLoad,65536)){ if(comparecase(FXPNGImage::fileExt,ext)==0){ icon=new FXPNGIcon(app); } else if(comparecase(FXJPGImage::fileExt,ext)==0 || comparecase("jpeg",ext)==0){ icon=new FXJPGIcon(app); } else if(comparecase(FXBMPIcon::fileExt,ext)==0){ icon=new FXBMPIcon(app); } else if(comparecase(FXGIFIcon::fileExt,ext)==0){ icon=new FXGIFIcon(app); } else if(comparecase(FXICOIcon::fileExt,ext)==0 || comparecase("cur",ext)==0){ icon=new FXICOIcon(app); } else { icon=NULL; } if(icon){ icon->setOptions(IMAGE_SHMI|IMAGE_SHMP); if(icon->loadPixels(store)) return icon; delete icon; icon=NULL; } } return NULL; } void GMIconTheme::clear_svg_cache() { #ifdef DEBUG fxmessage("clear svg cache\n"); #endif FXFile::removeFiles(get_svg_cache(),true); } FXString GMIconTheme::get_svg_cache() { return GMApp::getCacheDirectory(false) + CACHE_SVG_NAME; } void GMIconTheme::loadIcon(FXIconPtr & icon,const FXString & pathlist,FXint size,const FXchar * value,const FXColor blendcolor) { FXIcon * ic=NULL; FXString name,path,item; FXint beg,end; FXString file = value; FXString png = file + ".png"; FXString svg = file + ".svg"; ///FIXME: Linux/Unix only for(beg=0; pathlist[beg]; beg=end){ while(pathlist[beg]==PATHLISTSEP) beg++; for(end=beg; pathlist[end] && pathlist[end]!=PATHLISTSEP; end++){} if(beg==end) break; item=FXPath::expand(pathlist.mid(beg,end-beg)); path=FXPath::absolute(item,png); if(FXStat::exists(path)){ name.adopt(path); break; } if (rsvg) { path=FXPath::absolute(item,svg); if(FXStat::exists(path)){ FXString dest = get_svg_cache() + PATHSEPSTRING + GMStringVal(size); FXString target = dest + PATHSEPSTRING + svg + ".png"; if (!FXStat::exists(target)) { gm_make_path(dest); #ifdef DEBUG fxmessage("make %s\n",target.text()); #endif if (system(GMStringFormat("rsvg-convert --format=png --width=%d --height=%d -o %s %s\n",size,size,target.text(),path.text()).text())==0){ name.adopt(target); break; } } else { name.adopt(target); break; } } } } if (!name.empty()) ic=loadIcon(name); if (ic==NULL) ic = new FXIcon(app,NULL,0,IMAGE_OWNED,size,size); if (icon) { icon->destroy(); icon->setData(ic->getData(),ic->getOptions(),ic->getWidth(),ic->getHeight()); FXImageOwner::clear(ic); delete ic; } else { icon=ic; } icon->blend(blendcolor); FXIconThreshold::set(icon); icon->create(); } void GMIconTheme::loadSmall(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){ if (iconsets.no()) loadIcon(icon,iconsets[set].small,smallsize,value,blendcolor); else loadIcon(icon,FXString::null,smallsize,value,blendcolor); } void GMIconTheme::loadMedium(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){ if (iconsets.no()) loadIcon(icon,iconsets[set].medium,mediumsize,value,blendcolor); else loadIcon(icon,FXString::null,mediumsize,value,blendcolor); } void GMIconTheme::loadLarge(FXIconPtr & icon,const FXchar * value,const FXColor blendcolor){ if (iconsets.no()) loadIcon(icon,iconsets[set].large,largesize,value,blendcolor); else loadIcon(icon,FXString::null,largesize,value,blendcolor); } void GMIconTheme::loadResource(FXIconPtr & icon,const unsigned char * data,const char * type) { FXIconSource source(app); FXIcon * newicon = source.loadIconData(data,type); FXASSERT(newicon); if (icon) { icon->destroy(); icon->setData(newicon->getData(),newicon->getOptions(),newicon->getWidth(),newicon->getHeight()); FXImageOwner::clear(newicon); delete newicon; } else { icon=newicon; } } /* FXImage* GMIconTheme::loadLarge(const char * value) { FXImage * image = NULL; if (iconsets.no()) { FXASSERT(set>=0 && set=0 && setgetBaseColor(); const FXColor backcolor = app->getBackColor(); loadSmall(icon_copy,"edit-copy",backcolor); loadSmall(icon_cut,"edit-cut",backcolor); loadSmall(icon_paste,"edit-paste",backcolor); loadSmall(icon_delete,"edit-delete",backcolor); loadSmall(icon_undo,"edit-undo",backcolor); loadSmall(icon_play,"media-playback-start",backcolor); loadSmall(icon_pause,"media-playback-pause",backcolor); loadSmall(icon_next,"media-skip-forward",backcolor); loadSmall(icon_prev,"media-skip-backward",backcolor); loadSmall(icon_stop,"media-playback-stop",backcolor); loadSmall(icon_import,"folder",backcolor); loadSmall(icon_importfile,"document-open",backcolor); loadSmall(icon_exit,"exit",backcolor); loadSmall(icon_close,"window-close",backcolor); loadSmall(icon_find,"edit-find",basecolor); loadSmall(icon_sync,"view-refresh",basecolor); loadSmall(icon_album,"media-optical",basecolor); loadSmall(icon_artist,"system-users",basecolor); loadSmall(icon_genre,"bookmark-new",basecolor); loadSmall(icon_export,"document-save",basecolor); loadSmall(icon_homepage,"applications-internet",basecolor); loadSmall(icon_info,"help-browser",basecolor); loadSmall(icon_fullscreen,"window-fullscreen",backcolor); loadMedium(icon_source_library,"user-home",backcolor); loadMedium(icon_source_internetradio,"applications-internet",backcolor); loadMedium(icon_source_playlist,"user-bookmarks",backcolor); loadSmall(icon_playlist,"user-bookmarks",basecolor); loadSmall(icon_settings,"preferences-desktop",basecolor); loadSmall(icon_edit,"accessories-text-editor",basecolor); loadSmall(icon_sort,"view-sort-descending",basecolor); loadResource(icon_applogo,gogglesmm_32_png,"png"); loadResource(icon_applogo_small,gogglesmm_16_png,"png"); loadLarge(icon_nocover,"media-optical",backcolor); loadMedium(icon_audio_volume_high,"audio-volume-high",basecolor); loadMedium(icon_audio_volume_medium,"audio-volume-medium",basecolor); loadMedium(icon_audio_volume_low,"audio-volume-low",basecolor); loadMedium(icon_audio_volume_muted,"audio-volume-muted",basecolor); loadMedium(icon_play_toolbar,"media-playback-start",basecolor); loadMedium(icon_pause_toolbar,"media-playback-pause",basecolor); loadMedium(icon_next_toolbar,"media-skip-forward",basecolor); loadMedium(icon_prev_toolbar,"media-skip-backward",basecolor); loadMedium(icon_stop_toolbar,"media-playback-stop",basecolor); icon_applogo->blend(basecolor); icon_applogo_small->blend(basecolor); icon_applogo->create(); icon_applogo_small->create(); } FXint GMIconTheme::getNumThemes() const{ return iconsets.no(); } void GMIconTheme::setCurrentTheme(FXint s) { set=s; if (set>=0 && iconsets.no()) app->reg().writeStringEntry("user-interface","icon-theme",iconsets[set].dir.text()); else app->reg().writeStringEntry("user-interface","icon-theme",""); clear_svg_cache(); } FXint GMIconTheme::getCurrentTheme() const { return set; } FXString GMIconTheme::getThemeName(FXint i){ FXASSERT(i>=0 && igetItem(i); } FXbool isTrackItemSelected(FXint i) const { return tracklist->isItemSelected(i); } FXint getNumTracks() const { return tracklist->getNumItems() ; } void selectGenreItem(FXint item); void selectAlbumItem(FXint item); void selectArtistItem(FXint item); void selectTrackItem(FXint item); inline FXint getGenre(FXint index) const { return (FXint)(FXival)genrelist->getItemData(index); } inline FXint getArtist(FXint index) const { return (FXint)(FXival)artistlist->getItemData(index); } inline FXint getAlbum(FXint index) const { return (FXint)(FXival)albumlist->getItemData(index); } inline FXint getTrack(FXint index) const { return (FXint)(FXival)tracklist->getItemId(index); } FXbool listGenres(); FXbool listArtists(); FXbool listAlbums(); FXbool listTracks(); FXint getCurrent() const; FXint getNext(FXbool wrap=false); FXint getPrevious(); void setSource(GMSource * src); GMSource * getSource() const { return source; } FXString getTrackFilename(FXint i) const; void sortGenres() const; void sortArtists() const; void sortAlbums() const; void sortTracks() const; void resort(); void init(GMSource * src); void refresh(); void clear(); void mark(FXint item,FXbool show=true); void showCurrent(); void setSortMethod(FXint hdr,FXbool reverse=false); FXbool getSortReverse() const; void loadSettings(const FXString & key); void saveSettings(const FXString & key) const; void loadTrackSettings(const FXString & key); void saveTrackSettings(const FXString & key) const; void saveView() const; virtual ~GMTrackView(); }; #endif gogglesmm-0.12.7/src/GMCoverCache.h0000644000175000001440000000611311714631472015502 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMCOVERTHUMBS_H #define GMCOVERTHUMBS_H class GMImageMap; class GMCompressedImage; class FXIntMap : public FXHash { public: FXint insert(FXint name,FXint value) { return (FXint)(FXival)FXHash::insert((void*)(FXival)name,(void*)(FXival)value); } FXint replace(FXint name,FXint value) { return (FXint)(FXival)FXHash::replace((void*)(FXival)name,(void*)(FXival)value); } FXint remove(FXint name) { return (FXint)(FXival)FXHash::remove((void*)(FXival)name); } FXint find(FXint name) const { return (FXint)(FXival)FXHash::find((void*)(FXival)name); } FXint key(FXuint pos) const { return (FXint)(FXival)table[pos].name; } FXint value(FXuint pos) const { return (FXint)(FXival)table[pos].data; } void load(FXStream & store); void save(FXStream & store) const; }; class GMCoverCache : FXObject { FXDECLARE(GMCoverCache) protected: FXPtrListOf covers; FXPtrListOf buffers; FXIntMap map; FXint basesize; FXbool initialized; protected: FXImage * getCoverImage(FXint id); void adopt(GMCoverCache &); FXbool load(); FXString getCacheFile() const; public: enum { ID_COVER_LOADER = 1 }; public: long onCmdCoversLoaded(FXObject*,FXSelector,void*ptr); public: GMCoverCache(FXint size=128); void init(GMTrackDatabase*); void refresh(GMTrackDatabase*); void drawCover(FXint id,FXDC & dc,FXint x,FXint y); void markCover(FXint id); void reset(); void clear(); FXint getCoverSize() const { return basesize; } void insertCover(FXint id,GMCompressedImage*); void save() const; ~GMCoverCache(); }; #endif gogglesmm-0.12.7/src/GMAudioScrobbler.cpp0000644000175000001440000012244312063216173016732 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2010 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "gmutils.h" #include "ap_buffer.h" #include "ap_http.h" #include "ap_xml_parser.h" #include "GMAudioScrobbler.h" #ifdef HAVE_GCRYPT #include "gcrypt.h" #else #include "md5.h" #endif using namespace ap; /****************************************************************************** * * D E F I N E S * ******************************************************************************/ #define MAX_HANDSHAKE_TIMEOUT 7200 #define MIN_HANDSHAKE_TIMEOUT 60 #define DISABLE_HANDSHAKE_TIMEOUT 0 /// Old Style #define CLIENT_ID "gmm" #define CLIENT_VERSION "0.1" /// New Style #define CLIENT_KEY "76525254135cc544d13d381514222c56" #define CLIENT_SECRET "09397d5d6a55858a6883735b7cb694f7" #define SCROBBLER_CACHE_FILE PATHSEPSTRING ".goggles" PATHSEPSTRING "scrobbler.cache" #define LASTFM_URL "http://ws.audioscrobbler.com:80/2.0/" #define LASTFM_OLD_URL "http://post.audioscrobbler.com:80" #define LIBREFM_URL "http://turtle.libre.fm:80" /// Error codes returned by last.fm enum { LASTFM_ERROR_UNKNOWN = 0, LASTFM_ERROR_TOKEN_UNAUTHORIZED = 14, LASTFM_ERROR_TOKEN_EXPIRED = 15, LASTFM_ERROR_BADSESSION = 9, LASTFM_ERROR_OFFLINE = 11, LASTFM_ERROR_UNAVAILABLE = 16, LASTFM_ERROR_KEY_INVALID = 10, LASTFM_ERROR_KEY_SUSPENDED = 26 }; /* 1 : This error does not exist 2 : Invalid service -This service does not exist 3 : Invalid Method - No method with that name in this package 4 : Authentication Failed - You do not have permissions to access the service 5 : Invalid format - This service doesn't exist in that format 6 : Invalid parameters - Your request is missing a required parameter 7 : Invalid resource specified 8 : Operation failed - Most likely the backend service failed. Please try again. 9 : Invalid session key - Please re-authenticate 10 : Invalid API key - You must be granted a valid key by last.fm 11 : Service Offline - This service is temporarily offline. Try again later. 12 : Subscribers Only - This station is only available to paid last.fm subscribers 13 : Invalid method signature supplied 14 : Unauthorized Token - This token has not been authorized 15 : This item is not available for streaming. 16 : The service is temporarily unavailable, please try again. 17 : Login: User requires to be logged in 18 : Trial Expired - This user has no free radio plays left. Subscription required. 19 : This error does not exist 20 : Not Enough Content - There is not enough content to play this station 21 : Not Enough Members - This group does not have enough members for radio 22 : Not Enough Fans - This artist does not have enough fans for for radio 23 : Not Enough Neighbours - There are not enough neighbours for radio 24 : No Peak Radio - This user is not allowed to listen to radio during peak usage 25 : Radio Not Found - Radio station not found 26 : API Key Suspended - This application is not allowed to make requests to the web services 27 : Deprecated - This type of request is no longer supported */ /****************************************************************************** * * H E L P E R F U N C T I O N S * ******************************************************************************/ FXbool init_gcrypt() { #ifdef HAVE_GCRYPT if (!gcry_check_version(GCRYPT_VERSION)) { fxwarning("libgcrypt version mismatch"); return false; } gcry_control(GCRYCTL_DISABLE_SECMEM,0); gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0); #endif return true; } static void checksum(FXString & io){ if (io.empty()) return; #ifdef HAVE_GCRYPT FXuchar digest[16]; gcry_md_hash_buffer(GCRY_MD_MD5,(void*)digest,(const void*)io.text(),io.length()); #else md5_state_t pms; md5_byte_t digest[16]; md5_init(&pms); md5_append(&pms,(const md5_byte_t*)io.text(),io.length()); md5_finish(&pms,digest); #endif io.length(32); #if FOXVERSION < FXVERSION(1,7,0) for (FXint i=0,d=0;i<32;i+=2,d++) { io[i]=FXString::hex[(digest[d]/16)%16]; io[i+1]=FXString::hex[digest[d]%16]; } #else for (FXint i=0,d=0;i<32;i+=2,d++) { io[i]=Ascii::toLower(FXString::value2Digit[(digest[d]/16)%16]); io[i+1]=Ascii::toLower(FXString::value2Digit[digest[d]%16]); } #endif } #define URL_UNSAFE "#$-_.+!*'><()\\,%\"" // Always Encode #define URL_RESERVED ";/?:@=&" // Only encode if not used as reserved by scheme /**********************************************************************************************************/ void GMAudioScrobblerTrack::clear() { artist.clear(); album.clear(); title.clear(); duration=0; no=0; timestamp=0; loveban=0; } void GMAudioScrobblerTrack::save(FXStream & store) const { store << artist; store << album; store << title; store << duration; store << no; store << timestamp; store << loveban; } void GMAudioScrobblerTrack::load(FXStream & store) { store >> artist; store >> album; store >> title; store >> duration; store >> no; store >> timestamp; store >> loveban; } class ServiceResponse : public XMLStream { protected: FXbool status; FXint code; FXString message; FXString key; FXString token; protected: FXint elem; protected: FXint begin(const FXchar *,const FXchar**); void data(const FXchar *,FXint len); void end(const FXchar *); void parse_lfm_atts(const FXchar **); void parse_lfm_error_atts(const FXchar **); public: enum { Elem_None, Elem_LastFM, Elem_LastFM_Error, Elem_LastFM_Token, Elem_LastFM_Session, Elem_LastFM_Session_Key, }; public: ServiceResponse(); ~ServiceResponse(); FXbool getStatus() const { return status; } FXint getErrorCode() const { return code; } const FXString & getErrorMessage() const { return message; } const FXString & getSessionKey() const { return key; } const FXString & getToken() const { return token; } }; ServiceResponse::ServiceResponse() : elem(Elem_None) { } ServiceResponse::~ServiceResponse() { } void ServiceResponse::parse_lfm_atts(const FXchar ** attributes) { status=false; for (FXint i=0;attributes[i];i+=2){ if (compare(attributes[i],"status")==0) { if (comparecase(attributes[i+1],"ok")==0){ status=true; } } } } void ServiceResponse::parse_lfm_error_atts(const FXchar ** attributes) { FXString cd; for (FXint i=0;attributes[i];i+=2){ if (compare(attributes[i],"code")==0) { cd=attributes[i+1]; code=GMIntVal(cd); } } } FXint ServiceResponse::begin(const FXchar * element,const FXchar ** attributes){ switch(elem) { case Elem_None: { if (compare(element,"lfm")==0) { parse_lfm_atts(attributes); elem=Elem_LastFM; return 1; } } break; case Elem_LastFM: { if (compare(element,"error")==0) { parse_lfm_error_atts(attributes); elem=Elem_LastFM_Error; return 1; } else if (compare(element,"session")==0) { elem=Elem_LastFM_Session; return 1; } else if (compare(element,"token")==0) { elem=Elem_LastFM_Token; return 1; } } break; case Elem_LastFM_Session: { if (compare(element,"key")==0) { elem=Elem_LastFM_Session_Key; return 1; } } break; default: return 0; // skip } return 0; } void ServiceResponse::data(const FXchar* data,FXint len){ if (elem==Elem_LastFM_Error) { message.assign(data,len); } else if (elem==Elem_LastFM_Session_Key) { key.assign(data,len); } else if (elem==Elem_LastFM_Token) { token.assign(data,len); } } void ServiceResponse::end(const FXchar*) { switch(elem){ case Elem_LastFM_Session_Key : elem=Elem_LastFM_Session; break; case Elem_LastFM_Token : case Elem_LastFM_Error : case Elem_LastFM_Session : elem=Elem_LastFM; break; case Elem_LastFM : elem=Elem_None; break; } } FXbool GMAudioScrobbler::post_request(const FXString & url,const FXString & message,FXString & output) { FXTRACE((60,"post_request %s - %s\n",url.text(),message.text())); HttpClient client; if (client.basic("POST",url, "Content-Type: application/x-www-form-urlencoded\r\n" "Connection: close\r\n", message)) { output = client.body(); return true; } else { FXTRACE((60,"post_request failed\n")); set_timeout(); return false; } } FXbool GMAudioScrobbler::get_request(const FXString & url,FXString & output) { FXTRACE((60,"get_request\n")); HttpClient client; if (client.basic("GET",url,"Connection: close\r\n")) { output = client.body(); return true; } else { FXTRACE((60,"get_request failed\n")); set_timeout(); return false; } } /****************************************************************************** * * C O N S T R U C T O R * ******************************************************************************/ GMAudioScrobbler::GMAudioScrobbler(FXObject* tgt,FXSelector msg) : flags(FLAG_NONE), feedback(FXApp::instance()), target(tgt), message(msg), started(false), mode(SERVICE_LASTFM), timeout(DISABLE_HANDSHAKE_TIMEOUT), nsubmitted(0), nfailed(0) { username=FXApp::instance()->reg().readStringEntry("LastFM","username",NULL); password=FXApp::instance()->reg().readStringEntry("LastFM","password",NULL); FXString uri = FXApp::instance()->reg().readStringEntry("LastFM","handshake-url",LASTFM_URL); if (uri==LASTFM_OLD_URL) { uri=LASTFM_URL; username.clear(); password.clear(); FXApp::instance()->reg().writeBoolEntry("LastFM","client-banned",false); } handshake_url = uri; mode=getService(); /// Get last session if (mode==SERVICE_LASTFM) { session=FXApp::instance()->reg().readStringEntry("LastFM","session",NULL); if (!session.empty()) { FXTRACE((60,"GMAudioScrobbler::GMAudioScrobbler - Session: %s\n",session.text())); nowplaying_url=handshake_url; submit_url=handshake_url; } } /// Check if we're banned if (compare(FXApp::instance()->reg().readStringEntry("LastFM","client-id",CLIENT_ID),CLIENT_ID)==0 && compare(FXApp::instance()->reg().readStringEntry("LastFM","client-version",CLIENT_VERSION),CLIENT_VERSION)==0){ if (FXApp::instance()->reg().readBoolEntry("LastFM","client-banned",false)) flags|=FLAG_BANNED; } else { /// using different client, reset banned flag FXApp::instance()->reg().writeBoolEntry("LastFM","client-banned",false); } /// Check if we should scrobble tracks or not. if (!FXApp::instance()->reg().readBoolEntry("LastFM","scrobble-tracks",false)) flags|=FLAG_DISABLED; FXApp::instance()->reg().writeStringEntry("LastFM","client-id",CLIENT_ID); FXApp::instance()->reg().writeStringEntry("LastFM","client-version",CLIENT_VERSION); load_queue(); } GMAudioScrobbler::~GMAudioScrobbler(){ save_queue(); } /****************************************************************************** * * P U B L I C A P I * ******************************************************************************/ FXuint GMAudioScrobbler::getService() { FXString host = GMURL::host(handshake_url); if (host=="ws.audioscrobbler.com") return SERVICE_LASTFM; else if (host=="turtle.libre.fm") return SERVICE_LIBREFM; else return SERVICE_CUSTOM; } void GMAudioScrobbler::service(FXuint s) { FXTRACE((60,"GMAudioScrobbler::service\n")); if (s==SERVICE_LASTFM || s==SERVICE_LIBREFM) { mutex_data.lock(); if (s==SERVICE_LASTFM) FXApp::instance()->reg().writeStringEntry("LastFM","handshake-url",LASTFM_URL); else FXApp::instance()->reg().writeStringEntry("LastFM","handshake-url",LIBREFM_URL); handshake_url=FXApp::instance()->reg().readStringEntry("LastFM","handshake-url",LASTFM_URL); nowplaying_url.clear(); submit_url.clear(); session.clear(); token.clear(); flags|=FLAG_SERVICE; flags&=~FLAG_BADAUTH|FLAG_TIMEOUT|FLAG_BANNED|FLAG_BADTIME; username.clear(); password.clear(); FXApp::instance()->reg().writeStringEntry("LastFM","username",username.text()); FXApp::instance()->reg().writeStringEntry("LastFM","password",password.text()); FXApp::instance()->reg().writeStringEntry("LastFM","session",""); FXApp::instance()->reg().writeBoolEntry("LastFM","client-banned",false); mode=s; reset_timeout(); mutex_data.unlock(); wakeup(); } } void GMAudioScrobbler::login(const FXString & user,const FXString & pass) { FXTRACE((60,"GMAudioScrobbler::login\n")); mutex_data.lock(); flags&=~FLAG_DISABLED; if ( (flags&FLAG_BANNED) || (flags&FLAG_BADTIME) ) { mutex_data.unlock(); shutdown(); } else { if (mode==SERVICE_LIBREFM) { FXString newpass=pass; checksum(newpass); if (user!=username || newpass!=password) { username=user; password=newpass; FXApp::instance()->reg().writeStringEntry("LastFM","username",username.text()); FXApp::instance()->reg().writeStringEntry("LastFM","password",password.text()); flags|=FLAG_LOGIN_CHANGED; flags&=~FLAG_BADAUTH; mutex_data.unlock(); if (username.empty() || password.empty()) shutdown(); else runTask(); } else { mutex_data.unlock(); } } else { flags|=FLAG_LOGIN_CHANGED; flags&=~FLAG_BADAUTH; mutex_data.unlock(); runTask(); } } } void GMAudioScrobbler::nudge(){ FXTRACE((60,"GMAudioScrobbler::nudge\n")); if (started) { mutex_data.lock(); flags|=FLAG_NETWORK; mutex_data.unlock(); wakeup(); } } FXbool GMAudioScrobbler::can_submit() { if (getService()==SERVICE_LASTFM) return !( (flags&FLAG_DISABLED) || (flags&FLAG_BANNED) || (flags&FLAG_BADAUTH) || (flags&FLAG_BADTIME)); else return !( (flags&FLAG_DISABLED) || (flags&FLAG_BANNED) || (flags&FLAG_BADAUTH) || (flags&FLAG_BADTIME) || username.empty() || password.empty() ); } void GMAudioScrobbler::nowplaying(GMTrack & info){ mutex_data.lock(); if (!can_submit()) { mutex_data.unlock(); shutdown(); } else { nowplayingtrack=GMAudioScrobblerTrack(1,info,0); mutex_data.unlock(); runTask(); } } void GMAudioScrobbler::submit(FXlong timestamp,GMTrack & info){ if (info.time<30) return; mutex_data.lock(); if (!can_submit()) { mutex_data.unlock(); shutdown(); } else { submitqueue.append(GMAudioScrobblerTrack(timestamp,info,0)); mutex_data.unlock(); runTask(); } } void GMAudioScrobbler::loveban(GMTrack & /*info*/, FXint /*loveban*/){ #if 0 mutex_data.lock(); if (!can_submit()) { mutex_data.unlock(); shutdown(); } else { submitqueue.append(GMAudioScrobblerTrack(0,info,loveban)); mutex_data.unlock(); runTask(); } #endif return; } void GMAudioScrobbler::wakeup(){ mutex_task.lock(); condition_task.signal(); mutex_task.unlock(); } void GMAudioScrobbler::runTask() { if (!started) { start(); started=true; } else { wakeup(); } } void GMAudioScrobbler::shutdown(){ if (started) { mutex_data.lock(); flags|=FLAG_SHUTDOWN; mutex_data.unlock(); wakeup(); join(); started=false; } /// Save Session FXApp::instance()->reg().writeStringEntry("LastFM","session",session.text()); FXApp::instance()->reg().writeBoolEntry("LastFM","client-banned",(flags&FLAG_BANNED)); } void GMAudioScrobbler::disable(){ if (started) { mutex_data.lock(); flags|=FLAG_SHUTDOWN|FLAG_DISABLED; mutex_data.unlock(); wakeup(); join(); started=false; } FXApp::instance()->reg().writeBoolEntry("LastFM","scrobble-tracks",false); } void GMAudioScrobbler::enable() { mutex_data.lock(); flags&=~FLAG_DISABLED; flags&=~FLAG_SHUTDOWN; mutex_data.unlock(); FXApp::instance()->reg().writeBoolEntry("LastFM","scrobble-tracks",true); } FXString GMAudioScrobbler::getUsername() { FXMutexLock lock(mutex_data); return username; } FXbool GMAudioScrobbler::hasPassword(){ FXMutexLock lock(mutex_data); return !password.empty(); } FXbool GMAudioScrobbler::isBanned(){ FXMutexLock lock(mutex_data); return (flags&FLAG_BANNED); } FXbool GMAudioScrobbler::isEnabled(){ FXMutexLock lock(mutex_data); return !(flags&FLAG_DISABLED); } /****************************************************************************** * * P R O T E C T E D A P I * ******************************************************************************/ void GMAudioScrobbler::load_queue(){ FXTRACE((60,"GMAudioScrobbler::load_queue\n")); FXuint version,size; FXString filename = FXSystem::getHomeDirectory() + SCROBBLER_CACHE_FILE; FXFileStream store; if (store.open(filename,FXStreamLoad)){ store >> version; if (version==20080501) { store >> size; submitqueue.no(size); for (FXint i=0;i %d entries\n",submitqueue.no())); FXuint version=20080501; FXString filename = FXSystem::getHomeDirectory() + SCROBBLER_CACHE_FILE; if (submitqueue.no()) { FXFileStream store; if (store.open(filename,FXStreamSave)){ store << version; store << submitqueue.no(); for (FXint i=0;i0) { #if FOXVERSION < FXVERSION(1,7,0) FXlong wakeuptime = FXThread::time()+((FXlong)timeout*1000000000LL); // absolute time #else FXlong wakeuptime = ((FXlong)timeout*1000000000LL); // relative time FXlong start = FXThread::time(); #endif while(1) { #if FOXVERSION < FXVERSION(1,7,0) FXTRACE((60,"GMAudioScrobbler::waitForTask => %ld\n",timeout)); #else FXTRACE((60,"GMAudioScrobbler::waitForTask => %ld\n",wakeuptime)); #endif mutex_task.lock(); if (!condition_task.wait(mutex_task,wakeuptime)){ mutex_task.unlock(); return true; } else { mutex_task.unlock(); FXMutexLock lock(mutex_data); if (flags&FLAG_SHUTDOWN) return false; if (flags&FLAG_NETWORK) { flags&=~FLAG_NETWORK; return true; } #if FOXVERSION > FXVERSION(1,7,0) FXlong now = FXThread::time(); wakeuptime -= (now - start); start = now; /// Done waiting if (wakeuptime<=0) return true; #endif FXTRACE((60,"GMAudioScrobbler::waitForTask => reset\n")); } } } else { mutex_task.lock(); condition_task.wait(mutex_task); mutex_task.unlock(); } return true; } FXuchar GMAudioScrobbler::getNextTask() { FXTRACE((60,"GMAudioScrobbler::getNextTask\n")); FXMutexLock lock(mutex_data); if (flags&FLAG_SHUTDOWN){ flags&=~FLAG_SHUTDOWN; return TASK_SHUTDOWN; } if (flags&FLAG_SERVICE) { session.clear(); flags&=~FLAG_SERVICE; return TASK_NONE; } if (flags&FLAG_BADAUTH) return TASK_NONE; if (flags&FLAG_TIMEOUT) { flags&=~FLAG_TIMEOUT; return TASK_NONE; } if (flags&FLAG_LOGIN_CHANGED) { session.clear(); if (getService()==SERVICE_LASTFM) { if (!token.empty()) return TASK_LOGIN; else return TASK_AUTHENTICATE; } else { return TASK_LOGIN; } } if (submitqueue.no() || nowplayingtrack.timestamp) { if (session.empty()) { if (getService()==SERVICE_LASTFM) { if (!token.empty()) return TASK_LOGIN; else return TASK_AUTHENTICATE; } else { return TASK_LOGIN; } } else if (submitqueue.no()) return TASK_SUBMIT; else return TASK_NOWPLAYING; } return TASK_NONE; } FXint GMAudioScrobbler::run() { FXTRACE((60,"GMAudioScrobbler::run\n")); FXuchar next=TASK_NONE; do { while((next=getNextTask())!=TASK_NONE) { switch(next){ case TASK_AUTHENTICATE : authenticate(); break; case TASK_LOGIN : handshake(); break; case TASK_SUBMIT : submit(); break; case TASK_NOWPLAYING : nowplaying(); break; case TASK_SHUTDOWN : goto done; break; } } } while(waitForTask()); done: mutex_data.lock(); flags&=~FLAG_SHUTDOWN; flags&=~FLAG_LOGIN_CHANGED; flags&=~FLAG_TIMEOUT; mutex_data.unlock(); FXTRACE((60,"GMAudioScrobbler::run -> shutdown\n")); return 0; } void GMAudioScrobbler::set_timeout(){ flags|=FLAG_TIMEOUT; if (timeout==0) timeout=MIN_HANDSHAKE_TIMEOUT; else timeout=FXMIN(MAX_HANDSHAKE_TIMEOUT,timeout<<1); } void GMAudioScrobbler::reset_timeout(){ timeout=DISABLE_HANDSHAKE_TIMEOUT; } void GMAudioScrobbler::set_submit_failed() { FXTRACE((60,"GMAudioScrobbler::set_failed\n")); nfailed++; if (nfailed==3) { session.clear(); nfailed=0; } } void GMAudioScrobbler::create_token_request(FXString & request) { FXMutexLock lock(mutex_data); FXTRACE((60,"GMAudioScrobbler::create_token_request\n")); FXString signature="api_key"CLIENT_KEY"methodauth.getToken"CLIENT_SECRET; checksum(signature); request=GMStringFormat("method=auth.getToken&api_key="CLIENT_KEY"&api_sig=%s",signature.text()); flags&=~(FLAG_LOGIN_CHANGED); } void GMAudioScrobbler::process_token_response(const FXString & response){ FXMutexLock lock(mutex_data); if (flags&FLAG_LOGIN_CHANGED) return; ServiceResponse service; FXTRACE((60,"GMAudioScrobbler::process_token_response\n%s\n",response.text())); if (service.parse(response) && service.getStatus()) { token=service.getToken(); FXTRACE((60,"GMAudioScrobbler::process_token_response => token=%s\n",token.text())); FXString url="http://www.last.fm/api/auth/?api_key="CLIENT_KEY"&token="+token; feedback.message(target,FXSEL(SEL_OPENED,message),url.text(),url.length()); reset_timeout(); /// Reset timer set_timeout(); /// Let's wait at least 60s } else { FXTRACE((60,"last.fm service failed with code %d: %s\n",service.getErrorCode(),service.getErrorMessage().text())); flags|=FLAG_BADAUTH; } } FXuint GMAudioScrobbler::create_handshake_request(FXString & request) { FXMutexLock lock(mutex_data); FXTRACE((60,"GMAudioScrobbler::create_handshake_request\n")); if (mode==SERVICE_LASTFM) { FXString signature=GMStringFormat("api_key%smethodauth.getSessiontoken%s%s",CLIENT_KEY,token.text(),CLIENT_SECRET); checksum(signature); request=GMStringFormat("method=auth.getSession&api_key=%s&api_sig=%s&token=%s",CLIENT_KEY,signature.text(),token.text()); } else { FXlong timestamp = FXThread::time()/1000000000; FXString timestamp_text = GMStringVal(timestamp); FXString tk = password + timestamp_text; checksum(tk); request=GMStringFormat("/?hs=true&p=1.2&c="CLIENT_ID"&v="CLIENT_VERSION"&u=%s&t=%s&a=%s",username.text(),timestamp_text.text(),tk.text()); } flags&=~(FLAG_LOGIN_CHANGED); return mode; } void GMAudioScrobbler::process_handshake_response(const FXString & response){ FXMutexLock lock(mutex_data); if (flags&FLAG_LOGIN_CHANGED) return; FXTRACE((60,"GMAudioScrobbler::process_handshake_response\n%s",response.text())); if (mode==SERVICE_LASTFM) { ServiceResponse service; if (!service.parse(response) || !service.getStatus()){ FXTRACE((60,"last.fm service failed with code %d: %s\n",service.getErrorCode(),service.getErrorMessage().text())); switch(service.getErrorCode()) { case LASTFM_ERROR_TOKEN_EXPIRED : token.clear(); break; case LASTFM_ERROR_TOKEN_UNAUTHORIZED: case LASTFM_ERROR_OFFLINE : case LASTFM_ERROR_UNAVAILABLE : set_timeout(); break; default : flags|=FLAG_BADAUTH; break; } } else { session=service.getSessionKey(); nowplaying_url=handshake_url; submit_url=handshake_url; flags&=~FLAG_BADAUTH; reset_timeout(); } } else { FXString code; code=response.section('\n',0); if (compare(code,"OK",2)==0) { session = response.section('\n',1); nowplaying_url=response.section('\n',2); submit_url=response.section('\n',3); flags&=~FLAG_BADAUTH; reset_timeout(); } else if (compare(code,"BANNED",6)==0){ FXTRACE((60,"\t=> BANNED\n")); const FXchar msg[] = "This version of Goggles Music Manager is not supported\nby scrobbler service. Please upgrade to a newer version of GMM."; feedback.message(target,FXSEL(SEL_COMMAND,message),msg,ARRAYNUMBER(msg)); flags|=FLAG_BANNED; //FXApp::instance()->reg().writeBoolEntry("LastFM","client-banned",true); } else if (compare(code,"BADTIME",7)==0){ FXTRACE((60,"\t=> BADTIME\n")); const FXchar msg[] = "Unable submit tracks scrobbler service. The system time doesn't match\n" "the scrobbler server time. Please adjust your system time\n" "and restart GMM to start scrobbling."; feedback.message(target,FXSEL(SEL_COMMAND,message),msg,ARRAYNUMBER(msg)); flags|=FLAG_BADTIME; } else if (compare(code,"BADAUTH",7)==0){ FXTRACE((60,"\t=> BADAUTH\n")); const FXchar msg[] = "Unable to login to scrobbler service.\nUsername and password do not match."; feedback.message(target,FXSEL(SEL_COMMAND,message),msg,ARRAYNUMBER(msg)); flags|=FLAG_BADAUTH; } else if (compare(code,"FAILED",6)==0){ FXTRACE((60,"\t=> FAILED\n")); set_timeout(); } else { FXTRACE((60,"\t=> Unknown\n")); FXTRACE((60,"%s\n",response.text())); set_timeout(); } } } void GMAudioScrobbler::authenticate() { FXString request; FXString response; create_token_request(request); if (post_request(handshake_url,request,response)) process_token_response(response); } void GMAudioScrobbler::handshake() { FXString request; FXString response; FXbool result; if (create_handshake_request(request)==SERVICE_LASTFM) result = post_request(handshake_url,request,response); else result = get_request(handshake_url+request,response); if (result) process_handshake_response(response); } void GMAudioScrobbler::nowplaying() { FXString request; FXString response; create_nowplaying_request(request); if (post_request(nowplaying_url,request,response)) process_nowplaying_response(response); } void GMAudioScrobbler::submit() { FXString request; FXString response; create_submit_request(request); if (post_request(submit_url,request,response)) process_submit_response(response); } void GMAudioScrobbler::loveban() { FXString request; FXString response; create_loveban_request(request); if (post_request(submit_url,request,response)) process_loveban_response(response); } void GMAudioScrobbler::create_nowplaying_request(FXString & request) { FXMutexLock lock(mutex_data); FXTRACE((60,"GMAudioScrobbler::create_nowplaying_request\n")); if (mode==SERVICE_LASTFM) { FXString signature=GMStringFormat("album%s" "api_key"CLIENT_KEY "artist%s" "duration%d" "methodtrack.updateNowPlaying" "sk%s" "track%s" "trackNumber%d" CLIENT_SECRET, nowplayingtrack.album.text(), nowplayingtrack.artist.text(), nowplayingtrack.duration, session.text(), nowplayingtrack.title.text(), nowplayingtrack.no); checksum(signature); request=GMStringFormat("method=track.updateNowPlaying" "&track=%s" "&artist=%s" "&album=%s" "&trackNumber=%d" "&duration=%d" "&api_key="CLIENT_KEY "&api_sig=%s" "&sk=%s", gm_url_encode(nowplayingtrack.title).text(), gm_url_encode(nowplayingtrack.artist).text(), gm_url_encode(nowplayingtrack.album).text(), nowplayingtrack.no, nowplayingtrack.duration, signature.text(), session.text()); } else { request=GMStringFormat("s=%s&a=%s&t=%s&b=%s&l=%d&n=%d&m",gm_url_encode(session).text(), gm_url_encode(nowplayingtrack.artist).text(), gm_url_encode(nowplayingtrack.title).text(), gm_url_encode(nowplayingtrack.album).text(), nowplayingtrack.duration, nowplayingtrack.no); } nowplayingtrack.clear(); } void GMAudioScrobbler::process_nowplaying_response(const FXString & response){ FXMutexLock lock(mutex_data); if (flags&FLAG_LOGIN_CHANGED) return; FXTRACE((60,"GMAudioScrobbler::process_nowplaying_response:\n %s\n",response.text())); if (mode==SERVICE_LASTFM) { ServiceResponse service; if (!service.parse(response) || !service.getStatus()) { FXTRACE((60,"last.fm service failed with code %d: %s\n",service.getErrorCode(),service.getErrorMessage().text())); switch(service.getErrorCode()) { case LASTFM_ERROR_UNKNOWN : case LASTFM_ERROR_OFFLINE : case LASTFM_ERROR_UNAVAILABLE : set_timeout(); break; case LASTFM_ERROR_BADSESSION : session.clear(); break; case LASTFM_ERROR_KEY_INVALID : case LASTFM_ERROR_KEY_SUSPENDED: flags|=FLAG_BANNED; break; default : flags|=FLAG_BADAUTH; break; } } } else { FXString response; FXString code=response.section('\n',0); FXTRACE((70,"Now Playing Response: %s\n\n",response.text())); if (compare(code,"BADSESSION",10)==0) { session.clear(); } } } void GMAudioScrobbler::create_submit_request(FXString & request) { FXMutexLock lock(mutex_data); FXTRACE((60,"GMAudioScrobbler::create_submit_request\n")); FXint i,s; FXint ntracks = FXMIN(50,submitqueue.no()); FXString signature; if (mode==SERVICE_LASTFM) { if (ntracks==1) { signature=GMStringFormat("album[0]%s" "api_key"CLIENT_KEY "artist[0]%s" "duration[0]%d" "methodtrack.scrobble" "sk%s" "timestamp[0]%u" "trackNumber[0]%d" "track[0]%s" CLIENT_SECRET, submitqueue[0].album.text(), submitqueue[0].artist.text(), submitqueue[0].duration, session.text(), submitqueue[0].getTimeStamp(), submitqueue[0].no, submitqueue[0].title.text()); } else if (ntracks<10) { for (i=0;i #include #include "gmdefs.h" #include "GMThread.h" #include "GMTrackDatabase.h" #include "GMSearch.h" #include "GMTag.h" #include "GMFilename.h" #include "GMIconTheme.h" #include "GMAnimImage.h" #include "icons.h" #if APPLICATION_BETA_DB > 0 #define DATABASE_FILENAME "goggles_beta.db" #else #define DATABASE_FILENAME "goggles.db" #endif struct GMThreadProgress { GMThreadProgress(){} virtual ~GMThreadProgress(){} }; struct GMImportProgress : public GMThreadProgress { FXint nfound; FXint ntotal; FXString dir; FXString file; GMImportProgress(); GMImportProgress(const GMImportProgress&); }; class GMDatabaseThread : public GMThread { protected: GMImportOptions options_import; GMTrackDatabase database; public: GMDatabaseThread(const GMImportOptions &,FXObject*); ~GMDatabaseThread(); FXbool open(); void parse(const FXString & filename,FXint filenum,GMTrack &); void sendProgress(GMThreadProgress * p); void fixEmptyTags(GMTrack&,FXint dirnum=-1); }; class GMImportThread : public GMDatabaseThread { protected: GMImportProgress progress; FXString topdir; FXStringList files; FXint playlist; FXint lastid; protected: virtual FXint run(); void import(); void listDirectory(const FXString &); public: GMImportThread(const FXStringList & list,const GMImportOptions &,FXint playlist,FXObject*); virtual ~GMImportThread(); }; class GMSyncThread : public GMImportThread { protected: GMSyncOptions options_sync; FXint nchanged; FXbool synctag; protected: virtual FXint run(); void sync(); void syncDirectory(const FXString &); public: GMSyncThread(const FXStringList & list,const GMImportOptions & io,const GMSyncOptions & so,FXint playlist,FXbool t,FXObject*); virtual ~GMSyncThread(); }; GMDatabaseThread::GMDatabaseThread(const GMImportOptions & io,FXObject*tgt) : GMThread(tgt), options_import(io) { if (options_import.default_field.trim().empty()) options_import.default_field="Untitled"; } GMDatabaseThread::~GMDatabaseThread(){ } void GMDatabaseThread::sendProgress(GMThreadProgress * p) { feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_PROGRESS),&p,sizeof(GMThreadProgress*)); } FXbool GMDatabaseThread::open() { FXString dir = FXSystem::getHomeDirectory() + PATHSEPSTRING + ".goggles"; FXString databasefilename = dir + PATHSEPSTRING + DATABASE_FILENAME; if (!database.init(databasefilename)){ const char * msg = fxtr("Unable to open the database"); feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_ERROR),msg,sizeof(msg)); running=false; return false; } return true; } void GMDatabaseThread::parse(const FXString & filename,FXint filenum,GMTrack & info){ info.mrl=filename; switch(options_import.parse_method) { case GMImportOptions::PARSE_TAG : info.loadTag(filename); break; case GMImportOptions::PARSE_FILENAME : GMFilename::parse(info,options_import.filename_template,(options_import.replace_underscores ? (GMFilename::OVERWRITE|GMFilename::REPLACE_UNDERSCORE) : (GMFilename::OVERWRITE))); GMTag::length(info); break; case GMImportOptions::PARSE_BOTH : info.loadTag(filename); if (info.title.empty() || info.artist.empty() || info.album.empty() || info.album_artist.empty() || info.genre.empty() ) { GMFilename::parse(info,options_import.filename_template,(options_import.replace_underscores ? (GMFilename::REPLACE_UNDERSCORE) : (0))); } break; } fixEmptyTags(info,filenum); } void GMDatabaseThread::fixEmptyTags(GMTrack & track,FXint dirnum) { if (track.title.empty()) track.title=options_import.default_field; if (track.album.empty()) track.album=options_import.default_field; if (track.album_artist.empty()){ if (track.artist.empty()) { track.album_artist=options_import.default_field; track.artist=options_import.default_field; } else { track.album_artist=track.artist; } } if (track.artist.empty()) track.artist=track.album_artist; if (track.genre.empty()) { track.genre=options_import.default_field; } if (options_import.track_from_filelist && dirnum>=0) track.no=dirnum+1; } struct GMSyncProgress : public GMThreadProgress { FXint current; FXint total; FXint ndeleted; FXint nupdated; GMSyncProgress() : current(0),total(0), ndeleted(0), nupdated(0) {} GMSyncProgress(FXint t) : current(0),total(t), ndeleted(0), nupdated(0) {} GMSyncProgress(const GMSyncProgress& o) : GMThreadProgress(o), current(o.current), total(o.total), ndeleted(o.ndeleted), nupdated(o.nupdated) {} /* void load(FXStream & store){ store >> current; store >> total; } void save(FXStream & store) const { store << current; store << total; } */ }; GMSyncThread::GMSyncThread(const FXStringList & list,const GMImportOptions & io,const GMSyncOptions & so,FXint p, FXbool t,FXObject*tgt) : GMImportThread(list,io,p,tgt),options_sync(so),nchanged(0),synctag(t) { } GMSyncThread::~GMSyncThread(){ } FXint GMSyncThread::run(){ if (!open()) return -1; database.beginDelete(); database.beginEdit(); sync(); if (options_sync.import_new && !options_sync.remove_all) import(); database.endEdit(false); database.endDelete((nchanged>0)); if (running) feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_DONE),NULL,0); return 1; } #if FOXVERSION < FXVERSION(1,7,0) #define TO_NANO_SECONDS(x) ((FXlong)(1000000000LL*x)) #else #define TO_NANO_SECONDS(x) (x) #endif void GMSyncThread::syncDirectory(const FXString & dir) { GMTrack info; FXIntList ids; FXLongList dates; FXStringList filenames; FXStat stat; if (!database.getTrackFilenames(ids,filenames,dates,dir)) { const char * msg = fxtr("Database Error: Unable to retrieve all filenames."); feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_ERROR),msg,sizeof(msg)); running=false; return; } GMSyncProgress progress(ids.no()); if (options_sync.remove_all) { for (FXint i=0;i dates[i])) { parse(filenames[i],-1,info); if (!database.updateTrack(ids[i],info)) { const char * msg = fxtr("Unable to update track"); feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_ERROR),msg,sizeof(msg)); running=false; } progress.nupdated++; nchanged++; } sendProgress(new GMSyncProgress(progress)); } } } void GMSyncThread::sync(){ if (files.no()) { for (FXint i=0;(ibegin(); for (FXint i=0;(icommit(); return; } lastid=id; if (playlist>=0) database.insertTrackInPlaylist(playlist,id); } } } } database.database()->commit(); } FXint GMImportThread::run(){ if (!open()) return 1; import(); if (running) feedback.message(target,FXSEL(SEL_COMMAND,GMThreadDialog::ID_THREAD_DONE),NULL,0); return 1; } void GMImportThread::listDirectory(const FXString & dir) { GMTrack info; #if FOXVERSION < FXVERSION(1,7,20) const FXuint matchflags=FILEMATCH_FILE_NAME|FILEMATCH_CASEFOLD|FILEMATCH_NOESCAPE; #else const FXuint matchflags=FXPath::PathName|FXPath::NoEscape|FXPath::CaseFold; #endif FXint id; FXString * files=NULL; FXint no = FXDir::listFiles(files,dir,"*",FXDir::AllDirs|FXDir::NoParent|FXDir::NoFiles); for (FXint i=0;(i=0) database.insertTrackInPlaylist(playlist,id); } } delete [] files; } FXDEFMAP(GMThreadDialog) GMThreadDialogMap[]={ FXMAPFUNC(SEL_CLOSE,0,GMThreadDialog::onCmdCancel), FXMAPFUNC(SEL_COMMAND,FXDialogBox::ID_CANCEL,GMThreadDialog::onCmdCancel), FXMAPFUNC(SEL_COMMAND,GMThreadDialog::ID_THREAD_DONE,GMThreadDialog::onThreadDone), FXMAPFUNC(SEL_COMMAND,GMThreadDialog::ID_THREAD_ERROR,GMThreadDialog::onThreadError), }; FXIMPLEMENT(GMThreadDialog,FXDialogBox,GMThreadDialogMap,ARRAYNUMBER(GMThreadDialogMap)) GMThreadDialog::GMThreadDialog() { thread=NULL; } GMThreadDialog::GMThreadDialog(FXWindow* owner) : FXDialogBox(owner,"Goggles Music Manager",DECOR_TITLE|DECOR_BORDER,0,0,0,0,0,0,0,0,0,0), thread(NULL){ FXIconSource source(getApp()); animation_image = GMIconTheme::instance()->loadMedium("process-working.png"); animation_size = GMIconTheme::instance()->getMediumSize(); if (animation_image) { gm_colorize_bitmap(animation_image,getApp()->getForeColor()); animation_image->blend(getApp()->getBackColor()); animation_image->create(); } } GMThreadDialog::~GMThreadDialog(){ delete thread; delete animation_image; } /// Run modal invocation of the dialog FXuint GMThreadDialog::execute(FXuint placement){ FXASSERT(thread); create(); show(placement); getApp()->refresh(); thread->start(); return getApp()->runModalFor(this); } long GMThreadDialog::onThreadDone(FXObject*,FXSelector,void*){ thread->join(); getApp()->stopModal(this,FALSE); hide(); return 1; } long GMThreadDialog::onThreadError(FXObject*,FXSelector,void*ptr){ const FXchar * msg = (FXchar*)ptr; thread->join(); FXMessageBox::error(this,MBOX_OK,fxtr("Fatal Error"),fxtrformat("%s\nPlease contact support if this error keeps occuring."),msg); getApp()->stopModal(this,false); hide(); return 1; } long GMThreadDialog::onCmdCancel(FXObject*,FXSelector,void*){ thread->dispose_and_join(); getApp()->stopModal(this,FALSE); hide(); return 1; } FXDEFMAP(GMSyncDatabase) GMSyncDatabaseMap[]={ FXMAPFUNC(SEL_COMMAND,GMSyncDatabase::ID_THREAD_PROGRESS,GMSyncDatabase::onThreadProgress), }; FXIMPLEMENT(GMSyncDatabase,GMThreadDialog,GMSyncDatabaseMap,ARRAYNUMBER(GMSyncDatabaseMap)) GMSyncDatabase::GMSyncDatabase(){ } GMSyncDatabase::GMSyncDatabase(FXWindow * owner,const FXStringList & files,const GMImportOptions & io,const GMSyncOptions & so,FXint playlist,FXbool synctags,FXFont * font) : GMThreadDialog(owner) { thread=new GMSyncThread(files,io,so,playlist,synctags,this); FXLabel*label; FXHorizontalFrame * header = new FXHorizontalFrame(this,LAYOUT_FILL_X,0,0,0,0,0,20,0,0,0,0); header->setBackColor(getApp()->getBackColor()); FXVerticalFrame * frame = new FXVerticalFrame(header,LAYOUT_FILL_X,0,0,0,0,0,0,0,0,0,0); label_title = new FXLabel(frame,tr("Updating Database..."),NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10,0,10,0); label_title->setBackColor(getApp()->getBackColor()); label_title->setFont(font); label = new FXLabel(frame,tr("Please wait. This may take a while."),NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10+30,0,0,10); label->setBackColor(getApp()->getBackColor()); if (animation_image) { GMAnimImage *animation = new GMAnimImage(header,animation_image,animation_size,FRAME_NONE|LAYOUT_CENTER_Y); animation->setBackColor(getApp()->getBackColor()); } new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_TOP); FXVerticalFrame * main = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); contentswitcher = new FXSwitcher(main,LAYOUT_FILL_X|LAYOUT_FILL_Y); FXVerticalFrame * content = new FXVerticalFrame(contentswitcher,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,15,15,15,15); label_sync = new FXLabel(content,"0 Files Removed, 0 Files Updated"); progressbar = new FXProgressBar(content,NULL,0,LAYOUT_FILL_X|FRAME_LINE|PROGRESSBAR_PERCENTAGE); FXMatrix * matrix = new FXMatrix(contentswitcher,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,15,15,15,15); new FXLabel(matrix,tr("New Tracks:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_count = new FXTextField(matrix,10,NULL,0,TEXTFIELD_READONLY|TEXTFIELD_INTEGER|LAYOUT_FILL_X|JUSTIFY_LEFT); text_count->disable(); text_count->setTextColor(FXRGB(0,0,255)); text_count->setText("0"); new FXLabel(matrix,tr("File:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_file = new FXTextField(matrix,40,NULL,0,TEXTFIELD_READONLY|LAYOUT_FILL_X); text_file->disable(); new FXLabel(matrix,tr("Directory:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_dir = new FXTextField(matrix,40,NULL,0,TEXTFIELD_READONLY|LAYOUT_FILL_X); text_dir->disable(); new FXSeparator(main,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,tr("&Cancel"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_CENTER_X|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); } GMSyncDatabase::~GMSyncDatabase(){ } long GMSyncDatabase::onThreadProgress(FXObject*,FXSelector,void*ptr){ GMThreadProgress * tp = reinterpret_cast(*((void**)ptr)); if (tp) { GMSyncProgress * sp = dynamic_cast(tp); if (sp) { if (contentswitcher->getCurrent()!=0) { label_title->setText(fxtr("Updating Database...")); contentswitcher->setCurrent(0); } label_sync->setText(GMStringFormat("%d File(s) Removed, %d Files(s) Updated",sp->ndeleted,sp->nupdated)); progressbar->setProgress(sp->current); progressbar->setTotal(sp->total); } else { GMImportProgress * ip = dynamic_cast(tp); if (ip) { if (contentswitcher->getCurrent()!=1) { label_title->setText(fxtr("Importing Files...")); contentswitcher->setCurrent(1); } text_count->setText(GMStringFormat("%d / %d",ip->nfound,ip->ntotal)); text_file->setText(ip->file); text_dir->setText(ip->dir); } } delete tp; } return 1; } FXDEFMAP(GMImportDatabase) GMImportDatabaseMap[]={ FXMAPFUNC(SEL_COMMAND,GMImportDatabase::ID_THREAD_PROGRESS,GMImportDatabase::onThreadProgress), }; FXIMPLEMENT(GMImportDatabase,GMThreadDialog,GMImportDatabaseMap,ARRAYNUMBER(GMImportDatabaseMap)) GMImportDatabase::GMImportDatabase(){ } GMImportDatabase::GMImportDatabase(FXWindow * owner,const FXStringList & files,const GMImportOptions & io,FXint playlist,FXFont * font) : GMThreadDialog(owner) { thread=new GMImportThread(files,io,playlist,this); FXLabel*label; FXHorizontalFrame * header = new FXHorizontalFrame(this,LAYOUT_FILL_X,0,0,0,0,0,20,0,0,0,0); header->setBackColor(getApp()->getBackColor()); FXVerticalFrame * frame = new FXVerticalFrame(header,LAYOUT_FILL_X,0,0,0,0,0,0,0,0,0,0); label = new FXLabel(frame,tr("Importing Files..."),NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10,0,10,0); label->setBackColor(getApp()->getBackColor()); label->setFont(font); label = new FXLabel(frame,tr("Please wait. This may take a while."),NULL,LAYOUT_FILL_X|JUSTIFY_LEFT|TEXT_AFTER_ICON,0,0,0,0,10+30,0,0,10); label->setBackColor(getApp()->getBackColor()); if (animation_image) { GMAnimImage *animation = new GMAnimImage(header,animation_image,animation_size,FRAME_NONE|LAYOUT_CENTER_Y); animation->setBackColor(getApp()->getBackColor()); } new FXSeparator(this,LAYOUT_FILL_X|SEPARATOR_GROOVE|LAYOUT_SIDE_TOP); FXVerticalFrame * main = new FXVerticalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); FXMatrix * matrix = new FXMatrix(main,2,MATRIX_BY_COLUMNS|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,15,15,15,15); new FXLabel(matrix,tr("New Tracks:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_count = new FXTextField(matrix,10,NULL,0,TEXTFIELD_READONLY|TEXTFIELD_INTEGER|LAYOUT_FILL_X|JUSTIFY_LEFT); text_count->disable(); text_count->setTextColor(FXRGB(0,0,255)); text_count->setText("0"); new FXLabel(matrix,tr("File:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_file = new FXTextField(matrix,40,NULL,0,TEXTFIELD_READONLY|LAYOUT_FILL_X); text_file->disable(); new FXLabel(matrix,tr("Directory:"),NULL,LABEL_NORMAL|LAYOUT_FILL_X|JUSTIFY_RIGHT|LAYOUT_CENTER_Y); text_dir = new FXTextField(matrix,40,NULL,0,TEXTFIELD_READONLY|LAYOUT_FILL_X); text_dir->disable(); new FXSeparator(main,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0); new GMButton(closebox,tr("&Stop Import"),NULL,this,FXDialogBox::ID_CANCEL,BUTTON_INITIAL|BUTTON_DEFAULT|LAYOUT_CENTER_X|FRAME_RAISED|FRAME_THICK,0,0,0,0, 20,20); } GMImportDatabase::~GMImportDatabase(){ } long GMImportDatabase::onThreadProgress(FXObject*,FXSelector,void*ptr){ GMImportProgress * p = reinterpret_cast(*((void**)ptr)); if (p) { text_count->setText(GMStringFormat("%d / %d",p->nfound,p->ntotal)); text_file->setText(p->file); text_dir->setText(p->dir); delete p; } return 1; } gogglesmm-0.12.7/src/GMSource.cpp0000644000175000001440000000656311525430601015273 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMList.h" #include "GMDatabase.h" #include "GMTrackDatabase.h" #include "GMTrackList.h" #include "GMTrackView.h" #include "GMWindow.h" #include "GMSource.h" #include "GMPlayerManager.h" #include "GMTag.h" #include "GMIconTheme.h" #include "GMClipboard.h" FXIMPLEMENT(GMSource,FXObject,NULL,0); GMSource::GMSource() : current_track(-1), sort_browse(NULL) { } GMSource::~GMSource() { } FXbool GMSource::findCurrent(GMTrackList * list,GMSource * src) { if (src->current_track==-1) return false; for (FXint i=0;igetNumItems();i++){ if (list->getItemId(i)==src->current_track) { list->setActiveItem(i); list->setCurrentItem(i); return true; } } return false; } FXbool GMSource::findCurrentArtist(GMList *,GMSource *){ return false; } FXbool GMSource::findCurrentAlbum(GMList *,GMSource *){ return false; } void GMSource::markCurrent(GMTrackList * list,FXint item) { current_track=-1; if (list->getNumItems()) { current_track = list->getItemId(item); } } FXint GMSource::getNumTracks() const{ return 0; } FXString GMSource::getTrackFilename(FXint) const{ return FXString::null; } FXbool GMSource::getTrack(GMTrack &) const{ return false; } FXbool GMSource::listGenres(GMList *,FXIcon *){ return false; } FXbool GMSource::listArtists(GMList *,FXIcon *,const FXIntList&){ return false; } FXbool GMSource::listAlbums(GMList *,FXIcon *,const FXIntList &,const FXIntList&){ return false; } FXbool GMSource::listTracks(GMTrackList *,const FXIntList &,const FXIntList&) { return false; } FXbool GMSource::genre_context_menu(FXMenuPane *){ return false; } FXbool GMSource::artist_context_menu(FXMenuPane *){ return false; } FXbool GMSource::album_context_menu(FXMenuPane *){ return false; } FXbool GMSource::track_context_menu(FXMenuPane *){ return false; } FXbool GMSource::source_context_menu(FXMenuPane *){ return false; } gogglesmm-0.12.7/src/GMTrackItem.h0000644000175000001440000001254511525430601015360 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMTRACKITEM_H #define GMTRACKITEM_H class GMTrackItem; class GMDBTrackItem : public GMTrackItem { public: static FXint max_time; static FXint max_queue; static FXint max_trackno; static FXint max_digits(FXint no); protected: FXString title; /* 4 - 8 */ FXString artist; /* 4 - 8 */ FXString album_artist; /* 4 - 8 */ FXString album; /* 4 - 8 */ FXString genre; /* 4 - 8 */ FXint time; /* 4 - 4 */ FXuint no; /* 4 - 4 */ FXint queue; /* 4 - 4 */ FXushort year; /* 2 - 2 */ FXushort album_year; /* 2 - 2 */ //FXuchar filetype; /* 1 - 1 */ public: static FXint browseSort(const GMTrackItem*,const GMTrackItem*); static FXint ascendingTitle(const GMTrackItem*,const GMTrackItem*); static FXint descendingTitle(const GMTrackItem*,const GMTrackItem*); static FXint ascendingTrack(const GMTrackItem*,const GMTrackItem*); static FXint descendingTrack(const GMTrackItem*,const GMTrackItem*); static FXint ascendingDisc(const GMTrackItem*,const GMTrackItem*); static FXint descendingDisc(const GMTrackItem*,const GMTrackItem*); static FXint ascendingQueue(const GMTrackItem*,const GMTrackItem*); static FXint descendingQueue(const GMTrackItem*,const GMTrackItem*); static FXint ascendingTime(const GMTrackItem*,const GMTrackItem*); static FXint descendingTime(const GMTrackItem*,const GMTrackItem*); static FXint ascendingAlbum(const GMTrackItem*,const GMTrackItem*); static FXint descendingAlbum(const GMTrackItem*,const GMTrackItem*); static FXint ascendingArtist(const GMTrackItem*,const GMTrackItem*); static FXint descendingArtist(const GMTrackItem*,const GMTrackItem*); static FXint ascendingAlbumArtist(const GMTrackItem*,const GMTrackItem*); static FXint descendingAlbumArtist(const GMTrackItem*,const GMTrackItem*); static FXint ascendingGenre(const GMTrackItem*,const GMTrackItem*); static FXint descendingGenre(const GMTrackItem*,const GMTrackItem*); static FXint ascendingYear(const GMTrackItem*,const GMTrackItem*); static FXint descendingYear(const GMTrackItem*,const GMTrackItem*); protected: GMDBTrackItem(){} protected: virtual const FXString * getColumnData(FXint i,FXString & t,FXuint &justify,FXint & max) const; public: GMDBTrackItem(FXint id,const FXchar * title,const FXchar * artist,const FXchar * album_artist,const FXchar * album,const FXchar * genre,FXint time,FXuint no,FXint queue,FXushort year,FXushort ayear); void setTrackQueue(FXint q) { queue=q; } FXint getTrackQueue() const { return queue; } /// Return Track Number FXint getTrackNumber() const { return no; } /// Return Track Title FXString getTrackTitle() const { return title; } virtual ~GMDBTrackItem(); }; class GMStreamTrackItem : public GMTrackItem { public: static FXint max_trackno; static FXint max_digits(FXint no); protected: FXString title; FXString artist; FXString genre; FXint bitrate; FXint no; public: static FXint ascendingTitle(const GMTrackItem*,const GMTrackItem*); static FXint descendingTitle(const GMTrackItem*,const GMTrackItem*); static FXint ascendingTrack(const GMTrackItem*,const GMTrackItem*); static FXint descendingTrack(const GMTrackItem*,const GMTrackItem*); static FXint ascendingGenre(const GMTrackItem*,const GMTrackItem*); static FXint descendingGenre(const GMTrackItem*,const GMTrackItem*); static FXint ascendingTime(const GMTrackItem*,const GMTrackItem*); static FXint descendingTime(const GMTrackItem*,const GMTrackItem*); protected: GMStreamTrackItem(){} protected: virtual const FXString * getColumnData(FXint i,FXString & t,FXuint &justify,FXint & max) const; public: GMStreamTrackItem(FXint id,const FXchar * title,const FXchar * genre,FXint no,FXint bitrate); /// Return Track Number FXint getTrackNumber() const { return no; } /// Return Track Title FXString getTrackTitle() const { return title; } virtual ~GMStreamTrackItem() {} }; #endif gogglesmm-0.12.7/src/GMAnimImage.h0000644000175000001440000000457111525430601015324 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef GMANIMIMAGE_H #define GMANIMIMAGE_H class GMAnimImage : public FXImageFrame { FXDECLARE(GMAnimImage) protected: FXuint index; FXuint imgw; FXuint imgh; FXuint nframes; FXuint nrow; FXuint ncol; protected: GMAnimImage(); private: GMAnimImage(const GMAnimImage&); GMAnimImage& operator=(const GMAnimImage&); public: enum { ID_TIMER = FXImageFrame::ID_LAST, ID_LAST }; public: long onPaint(FXObject*,FXSelector,void*); long onTimer(FXObject*,FXSelector,void*); public: /// Construct image frame and pass it an image GMAnimImage(FXComposite* p,FXImage *img,FXint base,FXuint opts=FRAME_SUNKEN|FRAME_THICK,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=0,FXint pr=0,FXint pt=0,FXint pb=0); virtual void hide(); virtual void show(); virtual void create(); /// Get default width virtual FXint getDefaultWidth(); /// Get default height virtual FXint getDefaultHeight(); ~GMAnimImage(); }; #endif gogglesmm-0.12.7/src/GMMessageChannel.cpp0000644000175000001440000001237111525430601016702 0ustar sxjusers/******************************************************************************** * * * I n t e r - T h r e a d M e s s a g i n g C h a n n e l * * * ********************************************************************************* * Copyright (C) 2006-2011 by Jeroen van der Zijp. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see * ********************************************************************************* * $Id: FXMessageChannel.cpp,v 1.11 2007/07/09 16:31:34 fox Exp $ * ********************************************************************************/ #include #include #include "gmdefs.h" #include "GMMessageChannel.h" /* Notes: - Inter-thread messaging is handy to have. - Redo this in terms of FXPipe when that becomes possible. - Because of unbelievably retarded design of Windows, we need to use an Event-object to actually signal the GUI thread when we've written something to the pipe. - Possible problem: should probably NOT reset Event unless pipe is empty. But are we actually falling out of MsgWaitForMultipleObject if Event is already signalled when we enter MsgWaitForMultipleObject? */ // Maximum message size #define MAXMESSAGE 8192 // Bad handle value #ifdef WIN32 #define BadHandle INVALID_HANDLE_VALUE #else #define BadHandle -1 #endif using namespace FX; /*******************************************************************************/ namespace FX { // Structure of message struct FXMessage { FXObject *target; // Message target FXSelector message; // Message type,id #if !(defined(__LP64__) || defined(_LP64) || (_MIPS_SZLONG == 64) || (__WORDSIZE == 64) || defined(_WIN64)) FXint pad; // Padding for 32-bit #endif FXint size; // Message size }; // Structure of message+payload struct FXDataMessage { FXObject *target; // Message target FXSelector message; // Message type,id #if !(defined(__LP64__) || defined(_LP64) || (_MIPS_SZLONG == 64) || (__WORDSIZE == 64) || defined(_WIN64)) FXint pad; // Padding for 32-bit #endif FXint size; // Message size FXlong data[MAXMESSAGE/sizeof(FXlong)]; }; // Map FXDEFMAP(FXMessageChannel) FXMessageChannelMap[]={ FXMAPFUNC(SEL_IO_READ,FXMessageChannel::ID_IO_READ,FXMessageChannel::onMessage) }; // Object implementation FXIMPLEMENT(FXMessageChannel,FXObject,FXMessageChannelMap,ARRAYNUMBER(FXMessageChannelMap)); // Initialize to empty FXMessageChannel::FXMessageChannel():app((FXApp*)-1L){ h[0]=h[1]=h[2]=BadHandle; } // Add handler to application FXMessageChannel::FXMessageChannel(FXApp* a):app(a){ if(::pipe(h)!=0){ throw FXResourceException("unable to create pipe."); } ::fcntl(h[0],F_SETFD,FD_CLOEXEC); ::fcntl(h[1],F_SETFD,FD_CLOEXEC); #if FOXVERSION < FXVERSION(1,7,0) app->addInput(h[0],INPUT_READ,this,ID_IO_READ); #else app->addInput(this,ID_IO_READ,h[0],INPUT_READ,NULL); #endif } // Fire signal message to target long FXMessageChannel::onMessage(FXObject*,FXSelector,void*){ FXDataMessage pkg; if(::read(h[0],&pkg,sizeof(FXMessage))==sizeof(FXMessage)){ if(0tryHandle(this,pkg.message,pkg.data); } return pkg.target && pkg.target->tryHandle(this,pkg.message,NULL); } return 0; } // Send a message to a target FXbool FXMessageChannel::message(FXObject* tgt,FXSelector msg,const void* data,FXint size){ FXMutexLock locker(m); FXMessage pkg; pkg.target=tgt; pkg.message=msg; #if !(defined(__LP64__) || defined(_LP64) || (_MIPS_SZLONG == 64) || (__WORDSIZE == 64) || defined(_WIN64)) pkg.pad=0; #endif pkg.size=size; if(::write(h[1],&pkg,sizeof(FXMessage))==sizeof(FXMessage)){ if(pkg.size<=0 || (::write(h[1],data,pkg.size)==pkg.size)){ return true; } } return false; } // Remove handler from application FXMessageChannel::~FXMessageChannel(){ app->removeInput(h[0],INPUT_READ); ::close(h[0]); ::close(h[1]); app=(FXApp*)-1L; } } gogglesmm-0.12.7/src/GMDBus.h0000644000175000001440000002141311644100175014326 0ustar sxjusers/******************************************************************************** * * * F O X D B U S S U P P O R T * * * ********************************************************************************* * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * ********************************************************************************/ #ifndef GMDBUS_H #define GMDBUS_H #ifndef DBUS_BUS_H #include #endif /** * GMDBus is a thin wrapper of DBusConnection with the purpose of integrating it * into the FOX event loop (1.6), so that activity on DBus will be properly handled. * DBusConnections may only be managed by one GMDBus. The APIs are strictly enforcing this * by keeping a global (threadsafe) map of GMDBus/DBusConnection references. ** * In the future I hope to support the new FXReactor framework in FOX. * */ class GMDBusManager; class GMDBus : public FXObject { FXDECLARE(GMDBus) private: DBusConnection * dc; private: GMDBus(const GMDBus &); GMDBus &operator=(const GMDBus&); public: enum { ID_HANDLE = 1, ID_DISPATCH, ID_LAST, }; public: long onHandleRead(FXObject*,FXSelector,void*); long onHandleWrite(FXObject*,FXSelector,void*); long onHandleExcept(FXObject*,FXSelector,void*); long onDispatch(FXObject*,FXSelector,void*); public: /** * Construct non active Dbus Connection Hook */ GMDBus(); /** * Open Standard Bus * return false if already managed by other FXDBusConnection */ FXbool open(DBusBusType bustype=DBUS_BUS_SESSION); /** * Return FXDBusConnection for given DBusConnection. Return NULL if not found. */ static GMDBus * find(DBusConnection * dc); /** * Init the event loop for all connections */ static void initEventLoop(); /** * Return DBUS version */ static FXString dbusversion(); /** * Setup Callback Hooks */ virtual void setup_event_loop(); /** * Return DBusConnection */ DBusConnection * connection() const { return dc; } /** * Returns whether we're connected or not */ FXbool connected() const; /** * Returns whether we're authenticated */ FXbool authenticated() const; /** * Flush */ void flush(); /** * Send with Reply */ FXbool sendWithReply(DBusMessage * msg,FXint timeout,FXObject*,FXSelector); /** * Send */ void send(DBusMessage * msg,FXuint & serial); void send(DBusMessage * msg); /** * Destructor. Existing DBusConnection will be unreffed. */ virtual ~GMDBus(); }; /* A Remote Object */ class GMDBusProxy : public FXObject { FXDECLARE(GMDBusProxy) protected: GMDBus * bus; /// Bus FXString name; /// Name FXString path; /// Path FXString interface; /// Interface protected: FXbool associated; /// Are we associated FXObject * target; /// Target object FXSelector message; /// Message ID protected: FXHash serial; protected: GMDBusProxy(); private: GMDBusProxy(const GMDBusProxy&); GMDBusProxy& operator=(const GMDBusProxy&); public: long onCreate(FXObject*,FXSelector,void*); long onDestroy(FXObject*,FXSelector,void*); long onReplaced(FXObject*,FXSelector,void*); long onMethod(FXObject*,FXSelector,void*); long onSignal(FXObject*,FXSelector,void*); public: GMDBusProxy(GMDBus*,const FXchar * name,const FXchar * path,const FXchar * interface); FXString getPath() const { return path; } FXString getName() const { return name; } FXString getInterface() const { return interface; } FXbool matchSerial(DBusMessage * msg); DBusMessage * method(const FXchar * method); void send(DBusMessage*,FXObject*,FXSelector); virtual ~GMDBusProxy(); }; #define DEBUG_DBUS_MESSAGE(msg) { \ FXTRACE((80,"-----%s-------\n",__func__)); \ FXTRACE((80,"type: %s\n",dbus_message_type_to_string(dbus_message_get_type(msg))));\ FXTRACE((80,"path: %s\n",dbus_message_get_path(msg))); \ FXTRACE((80,"member: \"%s\"\n",dbus_message_get_member(msg))); \ FXTRACE((80,"interface: %s\n",dbus_message_get_interface(msg))); \ FXTRACE((80,"sender: %s\n",dbus_message_get_sender(msg))); \ FXTRACE((80,"signature: %s\n",dbus_message_get_signature(msg))); } /* Some Helper Functions */ extern void gm_dbus_variant_append_basic(DBusMessageIter * iter,const FXchar * element_string,FXint element,const void * value); extern void gm_dbus_variant_append_string(DBusMessageIter * iter,const FXchar * value); extern void gm_dbus_variant_append_path(DBusMessageIter * iter,const FXchar * value); extern void gm_dbus_variant_append_int32(DBusMessageIter * iter,const FXint value); extern void gm_dbus_variant_append_uint32(DBusMessageIter * iter,const FXuint value); extern void gm_dbus_variant_append_bool(DBusMessageIter * iter,const dbus_bool_t value); extern void gm_dbus_variant_append_double(DBusMessageIter * iter,const FXdouble value); extern void gm_dbus_variant_append_long(DBusMessageIter * iter,const FXlong value); extern void gm_dbus_variant_append_string_list(DBusMessageIter * iter,const FXchar * data[]); extern void gm_dbus_variant_append_string_list(DBusMessageIter * iter,const FXStringList&); extern void gm_dbus_append_string(DBusMessageIter *iter,const FXString & value); extern void gm_dbus_append_string_pair(DBusMessageIter *iter,const FXchar * key,const FXchar * value); extern void gm_dbus_dict_append_int32(DBusMessageIter * dict,const FXchar * key,const FXint value); extern void gm_dbus_dict_append_uint32(DBusMessageIter * dict,const FXchar * key,const FXuint value); extern void gm_dbus_dict_append_string(DBusMessageIter * dict,const FXchar * key,const FXchar * value); extern void gm_dbus_dict_append_string(DBusMessageIter * dict,const FXchar * key,const FXString & value); extern void gm_dbus_dict_append_double(DBusMessageIter * dict,const FXchar * key,const FXdouble & value); extern void gm_dbus_dict_append_long(DBusMessageIter * dict,const FXchar * key,const FXlong & value); extern void gm_dbus_dict_append_path(DBusMessageIter * dict,const FXchar * key,const FXchar * value); extern void gm_dbus_dict_append_bool(DBusMessageIter * dict,const FXchar * key,const dbus_bool_t value); extern void gm_dbus_dict_append_string_list(DBusMessageIter * dict,const FXchar * key,const FXchar * data[]); extern void gm_dbus_dict_append_string_list(DBusMessageIter * dict,const FXchar * key,const FXStringList &); extern DBusHandlerResult gm_dbus_reply_string(DBusConnection * connection,DBusMessage * msg,const FXchar * xml); extern DBusHandlerResult gm_dbus_reply_uint_string(DBusConnection * connection,DBusMessage * msg,const FXuint val,const FXchar * xml); extern DBusHandlerResult gm_dbus_reply_int(DBusConnection * connection,DBusMessage * msg,const FXint value); extern DBusHandlerResult gm_dbus_reply_double(DBusConnection * connection,DBusMessage * msg,const FXdouble value); extern DBusHandlerResult gm_dbus_reply_unsigned_int(DBusConnection * connection,DBusMessage * msg,const FXuint value); extern DBusHandlerResult gm_dbus_reply_long(DBusConnection * connection,DBusMessage * msg,const FXlong value); extern DBusHandlerResult gm_dbus_reply_if_needed(DBusConnection * connection,DBusMessage * msg); extern DBusHandlerResult gm_dbus_reply_bool(DBusConnection*connection,DBusMessage*msg,const dbus_bool_t); extern DBusHandlerResult gm_dbus_reply_string_list(DBusConnection * connection,DBusMessage * msg,const FXchar * data[]); extern void gm_dbus_match_signal(DBusConnection*,const FXchar * path,const FXchar * interface,const FXchar * member); #endif gogglesmm-0.12.7/src/GMFetch.cpp0000644000175000001440000000610411670036173015062 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2007-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #include "gmdefs.h" #include "GMFetch.h" #include "GMPlayerManager.h" #include "ap_buffer.h" #include "ap_http.h" using namespace ap; GMFetch * GMFetch::fetch = NULL; GMFetch::GMFetch() : gui(FXApp::instance()) { } FXint GMFetch::run() { GMFetchResponse * response = new GMFetchResponse; response->url = url; HttpClient client; // HEAD request don't always work... if (client.basic("GET",url) && client.status.code==200) { response->content_type = client.getHeader("content-type"); if (response->content_type.find("audio/mpegurl")!=-1 || response->content_type.find("audio/x-mpegurl")!=-1 || response->content_type.find("application/pls+xml")!=-1 || response->content_type.find("audio/x-scpls")!=-1) { response->data=client.body(); } gui.message(GMPlayerManager::instance(),FXSEL(SEL_COMMAND,GMPlayerManager::ID_DOWNLOAD_COMPLETE),&response,sizeof(GMFetchResponse*)); } else { errormsg="Failed to retrieve"; gui.message(GMPlayerManager::instance(),FXSEL(SEL_COMMAND,GMPlayerManager::ID_DOWNLOAD_COMPLETE)); } return 0; } void GMFetch::init() { } void GMFetch::exit() { if (fetch) { if (fetch->running()) fetch->join(); delete fetch; fetch=NULL; } } void GMFetch::download(const FXString & url) { if (fetch==NULL) { fetch = new GMFetch(); } else { if (fetch->running()) fetch->join(); } fetch->url = url; fetch->start(); } void GMFetch::cancel_and_wait(){ if (fetch && fetch->running() ) { fetch->join(); } } FXbool GMFetch::busy(){ if (fetch && fetch->running() ) return true; else return false; } gogglesmm-0.12.7/src/GMAbout.h0000644000175000001440000000376211525430601014550 0ustar sxjusers/******************************************************************************* * Goggles Music Manager * ******************************************************************************** * Copyright (C) 2006-2011 by Sander Jansen. All Rights Reserved * * --- * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see http://www.gnu.org/licenses. * ********************************************************************************/ #ifndef FXABOUTDIALOG_H #define FXABOUTDIALOG_H class GMAboutDialog : public FXDialogBox { FXDECLARE(GMAboutDialog) private: FXFontPtr titlefont; FXFontPtr licensefont; FXIconPtr logo; private: void setup(); private: GMAboutDialog(){} GMAboutDialog(const GMAboutDialog&); GMAboutDialog& operator=(const GMAboutDialog&); public: /// Construct free-floating About dialog GMAboutDialog(FXApp* a); /// Construct dialog which will always float over the owner window GMAboutDialog(FXWindow* owner); /// Destructor virtual ~GMAboutDialog(); }; #endif gogglesmm-0.12.7/ChangeLog0000644000175000001440000006062712063216237014074 0ustar sxjusers0.12.7 - Support WAV files. - Minor optimizatons - Add disc number support in filename parser - Support NetworkManager 0.9 notifications. - Fixes to audioscrobbler. 0.12.6 - Fix xine 1.2 detection in configure. 0.12.5 - Fix memory leak. - Fix libre.fm support. - New authentication method for last.fm. - Improved compatibility/detection for m3u/pls urls when playing Internet Radio. - Removed libcurl dependency. 0.12.4 - Added Portuguese Translation by Sérgio Marques - Improved notification daemon compatibility - Support for latest FOX 1.7.29. - Added genre and location to mpris information. 0.12.3 - Do not pass unsupported GL_LINEAR_MIPMAP_LINEAR to GL_TEXTURE_MAG_FILTER. - Enable support for non-power-of-two textures now that Mesa 7.11-rc4 fixes the issue. - Fix incorrect usage of FXAutoPtr. - Fix parallel build. 0.12.2 - Gnome 3 compatibility updates - Fix infinite last.fm warnings when the system time is out of sync with the last.fm server time. - Merge title that were split into multiple entries in vorbiscomments. 0.12.1 - fix crash when right-clicking tray icon (issue 230) - timer fix in audioscrobbler for fox-1.7 0.12.0 - Updated Look and Feel. - Updated Czech Translation. - Allow relative paths when exporting playlists. - Support for taglib 1.7 - Remove support for old miniplayer - Fix audioscrobbler on FOX 1.7 0.11.6 - Updated Spanish Translation - Improved opengl compatibility in cover display. 0.11.5 - Fix ignored icon theme (issue 222) - Initial svg icon support through use of rsvg-convert (part of librsvg) utility. 0.11.4 - Link explicitly to X11, GL and GLU (issue 212). - Improved icon theme specification support. Now also load from ~/.icons, $XDG_DATA_DIRS/icons and /usr/share/pixmaps. - Properly initialize libgcrypt to avoid warnings. - Added button to get out of miniplayer mode and make the miniplayer behave the same as the regular browser window. (issue 196). - New additional shortcut to toggle between miniplayer mode and browser mode (Ctrl-M). - Miniplayer is resizeable and remember its size and position. It will no longer automatically resize itself. - Fix crash when importing with specific icon themes selected. (issue 218) - Add big-endian support to flac album art loading. (issue 218) 0.11.3 - Icon name in desktop file shouldn't have file extension - Fix disabled mp4 support. - Translation Updates 0.11.2 - Support for .oga files. - Allow scrobbling to last.fm or libre.fm. - Fix some threading issues in the audio scrobbler. 0.11.1 - Updated Hungarian Translation - Fixed MANDIR and LOCALEDIR not being defined by configure, resulting in locale data and manpages to be installed in root. 0.11.0 - Drop support for taglib 0.5.x, taglib-extras and internal asf/mp4 support. - Remove internal icon theme and depend only on external ones. - Depend optionally on gcrypt for md5 calculation. - Partial MPRIS v1 interface. 0.10.27 - configure cleanups - Use proper uri (file:// instead of file:) (issue 203). - Added man page. 0.10.26 - Backport new font dialog. - Use posix sh instead of bash for configure script. 0.10.25 - Fix build issue with older taglib releases (1.5.x). - Updated Czech translation. 0.10.24 - Support mp4 and ogg vorbis embedded album art. - New opengl based cover viewer which allows for smooth scaling of the album cover. If opengl is not available or slow, the old x11 cover viewer can be used instead, which now has an option to choose the displayed cover size. - Import Playlists (xspf, m3u and pls) (issue 123) - Export playlist title for xspf playlists. - Changed Open MRL -> Play File or Stream and improved the dialog to make it easier choosing a local file from disk. - Add conditional support to filename format. Window title may now also be customized. - Show import options when dragging or copy/pasting files. - Added Tooltip to trayicon showing the current playing track information. - Open directory of track with right click (issue 146) - Fix active track in playlist when reordering (issue 194). 0.10.23 - Unify package, application and executable name. - Don't grab keys we're not going to use (issue 189). 0.10.22 - Added Czech translation by David Vachulka. 0.10.21 - Fix build script issue. 0.10.20 - Tray icon background color may now be customized to improve look of the tray icon. - Don't try to install mo files we don't have when LINGUAS environment variable is set (issue 165) - Replace libfetch with libcurl. - Load album art from tag in the album browser as well. (issue 176) - Fix main library listing genres from the Radio Streams. 0.10.19 - Support media keys through the Gnome Settings Daemon. - Don't show import dialog when radio streams are in the database. (issue 154) - Use ewmh icon hint to specify application icon which should result in a nicer looking icon in the taskbar. - Fix various dbus event handling to prevent crashes (issue 159) 0.10.18 - Make some functions static that don't need global scope. - Be more flexible about the http return code (issue 147). - Fix crash when pressing delete on "All Arists/Genres/Albums" 0.10.17 - Russian Translation. 0.10.16 - Hungarian Translation. - Compilation fix for older taglib in combination with mp4. 0.10.15 - Add additional signal handler(s) to correctly save state on exit. - Fix focus getting stuck in Edit Track dialog. - Year field in edit track dialog should be empty if multiple tracks with different years are selected. - Support bmp and gif embedded album art. - Fix memory leak in embedded album art loader. 0.10.14 - Support for .m4b files. - Minor fixes. 0.10.13 - Take disc number into account when sorting. 0.10.12 - Updated German Translation 0.10.11 - Prevent crash when settting input focus on widgets when a FOX version with xim support is being used. - Fix timeout type mixup with FOX-1.6 vs FOX-1.7 0.10.10 - Fix crash when removing tracks from the library via a playlist. 0.10.9 - Fix segfault in certain cases when no track information is yet available. - Removed support for libdownload. - Fixed segfault when using libfetch. - Improved error checking when downloading m3u and pls files. 0.10.8 - New command line option (--tray) to start gmm minimized in tray. - Album Artist tag support for MP4 files. - Fix shortcut to toggle playback (issue 121) - Use buildin mp4/asf support from taglib 1.6 if available. - Rely on default genre list from taglib. - Build fixes. 0.10.7 - Fix compilation --without-new-remote (issue 113) - Fix duplicate hotkeys in preferences dialog (issue 112) 0.10.6 - Fix time/duration display to account for hours. - Fix critical bug when sending album art to notification daemon. - Support for fox-1.7.20. - Optionally use taglib-extras for MP4 and ASF support. - Allow other scrobbler compatible servers to be used. - Added French translation. 0.10.5 - Override all compiler flags if CFLAGS has been set. 0.10.4 - Minor translation fixes - Fix duplicate hotkey in new radio station dialog. - Fix exporting playlist. 0.10.3 - Translation fixes and updates. - Warn user when a incompatible (future) version of the database is encountered. - Fix compilation with taglib-1.4. 0.10.2 - Added Spanish translation. - Fix translations not working with FOX 1.7 (issue 100) 0.10.1 - Fix tray icon issues. - Added German translation. - Properly encode special characters in audio scrobbler now playing submitter. - Fix sorting of album list by year in playlists. - Do not grab "AnyKey" by checking return value of XKeysymToKeycode. 0.10.0 - Database Improvements: o Improved performance when modifying the database (importing & removing tracks) o Added fields for per track artist (issue 72) - Import Improvements: o Added "Sync Folder" capability, which can also update or remove tracks in the database if needed. o Added import exclusion filter for file and folders. (issue 84) o Redesigned import dialog. It now contains the import options that were previously in the preferences dialog. o Added a filename template input to grab track information from a filename. This replaces the less flexible "title from filename","album from directory" and "artist from directory". o Added option to choose where to read the track information from: filename, tag or both. o Replaced "Default Title", "Default Album", "Default Artist" and "Default Genre" with a single "Default Field" since most of time you would likely use the same text anyway. o Removed the Import File(s) option. I don't think it's needed that much, and it reduces the number of choices a user has to make. Importing single files can still be accomplished through drag-and-drop. o Remove wizard. Just show import dialog first time. - Other Improvements: o Added Localization Capability. (issue 3) o Added disc column to track view. o Allow multiple genre selection in browser. o Double click in artist and album list will start playing. o Added button to enable or disable last.fm scrobbler. o Equalizer with configurable presets. o Take into account the disc number when sorting albums. o Send cover art through dbus to notify daemon directly instead of saving it to disk. o allow to write tags when editing even if tracks have not been modified. o more flexible input to select which fields need to be searched (issue 51). o allow quoted strings in search field. o Support for Multimedia Keys. o Optionally display playing track in title bar. o The album list may now also be sorted by album year. - Audio Improvements: o The audio driver can now be changed. (issue 87) o Replay Gain (Only Ogg Vorbis, native FLAC and mp3 with APE tags). - Filename Renamer o The excluded character set may now be changed for the filename renamer. o Added year and disc parameters. - Tray Icon Improvements: o tray icon is now integrated within gmm. gmm-tray has been removed. o tray icon show/hide miniplayer as well. o volume may be controlled using the mousewheel. o middle mouse click will toggle between playing and pausing. - Fixes: o crash when sorting in Internet Radio view. o remember "Update Filename" setting in edit dialogs. o actually try alternative urls in PLS or m3u before failing completely. o correctly display playing track in playlists. o do not run event loop in dbus message callback. 0.9.18 - Fix: Add support for fox-1.7.18. - Fix: more url handling fixes. - Misc: code cleanups. 0.9.17 - Fix: fix crash showing dialogbox when audio device open fails on startup. 0.9.16 - Fix: Track-less songs should not be 0 (#62) - Fix: disable default key press processing in tracklist. - Fix: Update GUI when done playing. - Fix: incorrect tracklist state when using search filter. - Fix: workaround for older notification daemons that don't show '&'. - Fix: improved url handling. - New: add additional shortcut '/' for search filter. - New: When pressing the search hotkeys, existing search text will be selected. - New: New shortcuts for Repeat Off, Track and All. Added shortcut for Shuffle as well. - New: Made repeat radio buttons instead of checkbuttons. - New: Play file from the commandline. 0.9.15 - Fix: Prevent crash by checking if session and system bus are available. - Fix: don't show tray icon option if gmm-tray is not in $PATH. - Fix: compile issue when building with old remote. 0.9.14 - New: Threaded scrobbler submitter which should prevent locking the GUI during DNS lookups. - New: Tray Icon. (contributed by Olivier Duclos). - New: More complete dbus interface (required by the tray icon) - New: NetworkManager support to wakeup scrobbler if network connection becomes available. - New: Font and colors may now be updated from within GMM and require no application restart. - Misc: The filename template settings has been moved from the preferences panel to the tag editing dialogs. - Misc: Support for mugshot was removed. - Misc: Nicer application and tray icon by Olivier Duclos. - Fix: Incorrect track number was used when renaming files - Misc: build/installation improvements: xdg-icon-resource/xdg-desktop-menu are not used anymore. * All icons are installed in (prefix)/share/icons/hicolor/* * gmm.desktop is installed in (prefix)/share/applications * `make install` will run gtk-update-icon-cache (prefix)/share/icons/hicolor Support DESTDIR variable when running make instal: make DESTDIR=/some/package install This will install gmm in /some/package/(prefix)/bin/gmm 0.9.13 - Fix: Crash in miniplayer. 0.9.12 - Fix: Cover wasn't shown when switching to mini player. - Fix: Update highlighted track if tracks are dragged around. 0.9.11 - New: Support embedded cover art in flac files (jpg and png only). - New: Support last-fm 'now playing' notification. - New: Support album art in notification to notify-daemon. - New: DBus enabled version now also support the ability to control a running gmm from the command line. - New: Use "ALBUMARTIST" tag in Ogg / FLAC files and TPE2 for id3v2 tags for artist. 0.9.10 - New: Experimental support for libfetch on FreeBSD (untested). - New: Embedded cover art (id3v2 tags) now also supported in remote. - New: Make covers in remote slightly larger. - Fix: Compilation issue on FreeBSD. - Fix: Scrobbler only submitted one track at a time. - Fix: Scrobbler connection timeout was too large. 0.9.9 - Fix: Track play count and display were not always properly updated (in combination with gapless playback), This affected last-fm submission as well... - Fix: Crash in Edit Track dialog if mp4 file doesn't exist. - Fix: Current item in tracklist need to be updated when stop is pressed to be able to continue playing from the last played track. - Fix: Restore maximized/fullscreen state on start up. - Fix: Using the mouse wheel in the remote now also changes the volume. - Fix: Remote now also has a window icon. - New: Ctrl-Q now also works in the remote. - New: Experimental support for embedded cover art support in mp3 / flac with ID3v2 tags. 0.9.8 - Fix: files with '#' couldn't be opened anymore due to change in xine-1.1.9. - Fix: Improved Album Art search. Now looks for jpg,gif,png and bmp files in the directory of the music file. Gives higher priority to files found with the following names: cover,album, albumart,.folder,folder. - New: Added some webbrowser links to last-fm sign-up and Goggles Music Manager user group. 0.9.7 - Fix: Really fix Compilation issue on 32 bit systems. 0.9.6 - Fix: Compilation issue on 32 bit systems. 0.9.5 - Fix: fix url encoding to handle more unsafe characters 0.9.4 - New: Last-FM audio scrobbler support. - Fix: include instead of 0.9.3 - Fix: Fix configure columns dialog for FOX-1.7. Draw function wasn't properly overloaded. - Fix: Support new FXFontDesc api in FOX-1.7.17 0.9.2 - New: Configure Columns dialog can now also show/hide columns. (backport) - New: Turn on audio playback engine on startup is now a option. - New: Added Volume Control to Mini Player. - New: Show year column in track list. - New: Disc Number Support. - New: Improved Edit Track Dialog. - New: Ctrl-W now also closes the window (either quits the application, or toggles the remote). - Fix: Reflect column order in right click menu. - Fix: Use new dbus-1.2 api if available. Also show DBus version if available in about panel. - Fix: Remove Compiler Warnings (gcc 4.3). - Fix: Improved check if files are local or not which affects updating the GUI. 0.9.1 - Fix: Compilation issue with older xine. - Fix: Compilation issue with debug build. - Fix: Check for proper SQLite version during runtime. - Fix: Prevent the application from disappearing when using the old remote. - Fix: Added extra hint for new remote to show window title for certain window managers. - Fix: Some fixes to configure. 0.9.0 - New: Search Filter. - New: Change order of columns in track list. - New: Alternative Mini Player (old one still available through configure option). - New: Context menu for track list header. - New: Selection state in browser for each source. - New: Try raising existing music manager when starting without commandline arguments. - New: Support for Internet Radio Streams. - New: Support for ASF files. - New: Support for MP4 through TagLib. Removed old libmp4v2 support. - New: now uses the c++ taglib library instead of the c-bindings. - New: use bold italic font for playing track in tracklist. - New: Shuffle mode: play tracks in random order. - New: Repeat A-B mode: repeat section of a track. - New: Editing improvements. - New: When clearing the database, playlist entries may be optionally kept. - New: When removing tracks from database may be optionally deleted from disk as well. - New: Keyboard shortcuts for editing and deleting tracks. - New: Show audio/file properties in track edit dialog. - Fix: better path caching when inserting tracks (should increase speed). - Fix: Do not allocate icons before they're actually used (about and remote dialogs). - Fix: fix memory leak in browse sort. - Fix: Support modified fox-config on Gentoo. - Fix: Use [[ in build scripts instead of [. - Fix: Paste from gtk applications failed if it contained line feeds. - Fix: Only enable next/previous if more than 1 track is available. - Misc: Changed Full Screen shortcut to F12. Ctrl-F is now used for the search filter. - Misc: Build system is now more like autoconf/automake. - Misc: Disable default title/album/artist if options above are selected. 0.8.0 - New: Support creating custom playlists. - New: Don't show duplicate albums names when multiple artists are selected. - New: Added "All" entry to artist and album lists. - New: Export database and playlists to XSPF, PLS, Extended M3U, M3U and CSV. - New: Clipboard and drag-and-drop support for moving tracks to playlists and importing and exporting files. - New: Configurable toolbar docked on top or bottom, showing big or small icons with optional text. - New: Customizable Icon Theme. Either use buildin icons, or load from disk. - New: Animated icon in scan progress dialog. - New: Support year tag. - New: Support volume normalization plugin. - New: Database now also stores for each track: year, rating, import date, play date and play count. - New: Option to close audio device when playback is stopped. - New: Upgraded to more advanced build system. - New: Include Desktop Application Entry and Icon in distribution - New: New About Dialog. - New: Report An Issue link in Help Menu. - New: Changed License to GPL-3. - New: Warning dialog when FOX without PNG support is used. - New: Fullscreen mode (requires FOX-1.7.11). - Fix: Ctrl-A selection now works in all lists. - Fix: Do not import MP4 files that contain video. - Fix: Track titles are also now sorted using the leading keyword filter. - Fix: Editing Dialogs retain proper sorting order of genres,artists and albums. - Fix: Allow up to 4 digits in track number input in edit dialogs. - Fix: issue preventing filenames with '#' characters from playing. - Fix: compilation fix for older xine libraries. - Fix: status line now shows correct song in repeat mode. - Fix: sleeptimer now works properly in FOX 1.6. - Fix: Write xine configuration file on exit. - Fix: Don't recurse into directories that are symbolic links. 0.7.5 - Fix: Possible crash in empty track list due uninitialized variables. 0.7.4 - New: Added Sleep Timer. Stops playback after specified amount of time. - New: Implement command line options to control an already running music manager. - Fix: Reset Display after end playlist. - Fix: Remember import files directory as well. - Fix: Even more error handling in xine. 0.7.3 - Better playback error handling. - Only use path title (filename without extension) for track title in case of files without tags. - Track list now has multiple selection capability for easier tag editing. - Assign track numbers automatically based on the selection order in the track list. - Added Sorting Arrows on Genre,Artist and Album lists. - Added Genre Column in tracklist. - Better alignment for track numbers and times. - Playing track has now different background color. - Improved sorting. 0.7.2 - File naming options were not taking into account. 0.7.1 - Now supports renaming audio files during tag editing. - Add Statistics Information Dialog. - Speed up multiple selection in artist list. - Cleanup dead and unused code. - Minor Fixes. 0.7.0 - gapless playback support. - mp4 support is now optional. - Tag Editing Support. - Repeat Track Support. - Speed improvements in SQL database. - Minimize jumping of slider control when seeking. - Background color for every other row. - Import of single files now also possible. - Columns in tracklist are also now configurable in browse mode. - Fix Crash when clearing database and reimporting in List Mode. - Set default value for saving tag changes to file to false. - Manage own taglib string memory because taglib is leaking. - Also search for .m4p files. 0.6.2 - Ability to show directory contents in filemanager of selected song. - Added "repeat all" option which determines whether to restart playing from the beginning of the play list or not - FOX 1.7.x support. - Fixed Relative Path display in scan/search dialog. - Fixed Typos in welcome dialog. - Statusbar by default off now. - MP4 Tag Support [Read Only] 0.6.1 - New Progress Dialog during file scanning, which also includes the ability to cancel the scanning at any time. - Added support for flac and musepack. - Now depend on taglib for reading and writing tags. - Ability to hide status bar. - Support playing file from the command line arguments - Only allow one gmm to be started and send play request to already running gmm. 0.6.0 - Added some more icons. - Added userfriendly dialog at startup when database is empty. - Use more advanced sorting routine that can interpret numbers in strings. - Allow genre,artist and album list to be sorted in reverse. - Fixed bug with setting current category on startup. - Removed unused font which caused a crash. - Tracklist was not properly sorted at startup - FOX 1.5 -> FOX 1.6 0.5.3 - Ability to remove certain artist from the database. - FOX 1.4 -> FOX 1.5 0.5.2 - Add Multiple Selection in Artist and Album List. - Keep better track of last played track. - Columns in songlist can be configured by the user. 0.5.1 - More error checking in database handling. - Removed fastforward/fastbackward. - Fixed bug that prevented sorting on time in normal list mode when clicking header. - Columns in song list now remember their size. - Songlist remembers its sorting column and order. - Smart Sorting for lists. Skips common words like "the","a","an". This is a configurable option... - Change remote mouse click functionality: one click skips to next song, double click opens manager. - Remote Volume control changes volume immediately on first wheel mouse move. - Check for old database on startup and remove it if users wants it. We aks only once. - Remembers which displaymode it is in. - Added random "sort" mode. 0.5.0 - New Database backend. We're now using SQLite. Database file has changed from goggles.database to goggles.db. - While playing, if the volume is turned down to zero, playback will automatically pause. - Add Category/Genre List to GUI. - Fixed bug that prevented using Goggles Music Manager if FOX version was updated. - Xine is really slow at reading in tags. I put the old ogg vorbis tag reading back. MP3 is still done by Xine. - Added remote control window. - Added preferences panel. 0.2.6 - FOX 1.4 support. 0.2.5 - Added MP3 file support. - Removed editing capability of tag names for now. Hopefully we can add this back soon. - We now use xine to retrieve all tags from ogg and mp3 files. It might be slower than before. We might change that in the future again. 0.2.4 - You can now either import files into a existing database or create a new database. - While importing files, we now skip files that are already in the database. - Now has four GUI modes: Full, Compact, Slim and List. 0.2.3 - Initial Release. gogglesmm-0.12.7/COPYING0000644000175000001440000010451310651764222013351 0ustar sxjusers GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . gogglesmm-0.12.7/INSTALL0000644000175000001440000000145111670036316013342 0ustar sxjusersInstallation Instructions ------------------------- 1. Install all required dependencies: * FOX 1.6.x (recommended) or * FOX 1.7.x (latest development release, see README file for details) * xine-lib >= 1.1.16 * sqlite >= 3.6.3 * taglib >= 1.6.3 * expat * dbus 1.0.x (optional) * libgcrypt (optional) 2. Run the configure script: > ./configure 3. Compile > make 4. If everything compiled fine, you are ready to install Goggles Music Manager in its final location. By default this will be in /usr. Using the --prefix option on the configure command line you may change this to something else (eg. ./configure --prefix=/usr/local ) > su > make install 5. Run the software > gogglesmm gogglesmm-0.12.7/build/0000755000175000001440000000000012063216606013406 5ustar sxjusersgogglesmm-0.12.7/build/makepot0000644000175000001440000000302411442435643014774 0ustar sxjusers#------------------------------------------------------------------------------- # Make template #------------------------------------------------------------------------------- FOXDIR=../../../fox-1.6.37 INPUT="src/*.cpp src/*.h" xgettext -C --from-code=UTF-8 --msgid-bugs-address=s.jansen@gmail.com --package-name=gogglesmm --package-version=0.10.0 --copyright-holder="Sander Jansen" --keyword=tr:1 --keyword=fxtr:1 --keyword=notr:1 --keyword=fxtrformat:1 --flag=fxtrformat:1:c-format -o po/gogglesmm.pot $INPUT #INPUT="include/GMGenres.h" #xgettext -C -j -a --from-code=UTF-8 --msgid-bugs-address=s.jansen@gmail.com --package-name=gogglesmm --package-version=0.10.0 --copyright-holder="Sander Jansen" -o po/gogglesmm.pot $INPUT # FOX files INPUT="$FOXDIR/src/FXMessageBox.cpp \ $FOXDIR/src/FXColorSelector.cpp \ $FOXDIR/src/FXDirSelector.cpp \ $FOXDIR/src/FXFileList.cpp \ $FOXDIR/src/FXFileSelector.cpp \ $FOXDIR/src/FXReplaceDialog.cpp \ $FOXDIR/src/FXSearchDialog.cpp \ $FOXDIR/src/FXStatusLine.cpp" xgettext -C -j --from-code=UTF-8 --msgid-bugs-address=s.jansen@gmail.com --package-name=gogglesmm --package-version=0.10.0 --copyright-holder="Sander Jansen" --keyword=tr:1 -o po/gogglesmm.pot $INPUT # Additional non tr ones #INPUT="$FOXDIR/src/FXColorNames.cpp" #xgettext -C -j -a --from-code=UTF-8 --msgid-bugs-address=s.jansen@gmail.com --package-name=gogglesmm --package-version=0.10.0 --copyright-holder="Sander Jansen" -o po/gogglesmm.pot $INPUT for i in po/*.po do echo "Updating $i ..." msgmerge -U $i po/gogglesmm.pot done gogglesmm-0.12.7/build/version0000644000175000001440000000005612063216763015023 0ustar sxjusersMAJOR=0 MINOR=12 LEVEL=7 BETA_DB=0 BETA_APP=0 gogglesmm-0.12.7/build/byteorderdetect0000644000175000001440000000175011417360712016524 0ustar sxjusers#----------------------------------------------------------- # GOGGLES BUILD SYSTEM #----------------------------------------------------------- # # This will determine the byteorder # #----------------------------------------------------------- cd build makebyteorder() { cat > checkbyteorder.cpp <<__EOF int main() { if (sizeof(long int) == 4) { long int testInt = 0x12345678; char * pMem; pMem = (char *)&testInt; if (pMem[0] == 0x78) return 0; else return 1; } else if (sizeof(int) == 4) { int testInt = 0x12345678; char * pMem; pMem = (char *) &testInt; if (pMem[0] == 0x78) return 0; else return 1; } return 0; } __EOF } makebyteorder $CXX ${OUTPUTBIN} checkbyteorder checkbyteorder.cpp BYTEORDER=${BYTEORDER:-0} if [ -x checkbyteorder ] ; then ./checkbyteorder if [ $? -eq 1 ] ; then BYTEORDER=1 fi rm -rf checkbyteorder fi rm -rf checkbyteorder.cpp DEFINES="$DEFINES -DFOX_BIGENDIAN=${BYTEORDER}" cd .. gogglesmm-0.12.7/build/functions0000644000175000001440000000761711701202113015336 0ustar sxjusers#!/bin/sh #----------------------------- CFG="src/gmconfig.h" add_package_path() { if [ -n "$PKG_CONFIG_PATH" ] ; then PKG_CONFIG_PATH="$1/lib/pkgconfig:$1/lib64/pkgconfig:$1/share/pkgconfig:$PKG_CONFIG_PATH" else PKG_CONFIG_PATH="$1/lib/pkgconfig:$1/lib64/pkgconfig:$1/share/pkgconfig" fi export PKG_CONFIG_PATH } # Check for generic config in prefix #----------------------------------- check_in_prefix() { echo " Search for $1 >= $4.$5.$6 in $2 ... " if [ ! -x $2/bin/$3 ] ; then return 0 fi echo " Check $1 Config => FOUND" CONFIG_LIB=$($2/bin/$3 --libs) CONFIG_INCLUDE=$($2/bin/$3 --cflags) CONFIG_VERSION=$($2/bin/$3 --version) CONFIG_MAJOR=$(echo "${CONFIG_VERSION}" | cut -d. -f1) CONFIG_MINOR=$(echo "${CONFIG_VERSION}" | cut -d. -f2) CONFIG_LEVEL=$(echo "${CONFIG_VERSION}" | cut -d. -f3) CONFIG_PREFIX=$2 export CONFIG_PREFIX INCFLAGS="${INCFLAGS} ${CONFIG_INCLUDE} " LIBS="${LIBS} ${CONFIG_LIB} " # Make sure it is a compatible version #-------------------------------------------- if [ $CONFIG_MAJOR -lt $4 ] ; then echo " Check $1 Version => Unsupported ($CONFIG_MAJOR.$CONFIG_MINOR.$CONFIG_LEVEL)" return 0 fi if [ $CONFIG_MAJOR -eq $4 ] && [ $CONFIG_MINOR -lt $5 ] ; then echo " Check $1 Version => Unsupported ($CONFIG_MAJOR.$CONFIG_MINOR.$CONFIG_LEVEL)" return 0 fi if [ $CONFIG_MAJOR -eq $4 ] && [ $CONFIG_MINOR -eq $5 ] && [ $CONFIG_LEVEL -lt $6 ] ; then echo " Check $1 Version => Unsupported ($CONFIG_MAJOR.$CONFIG_MINOR.$CONFIG_LEVEL)" return 0 fi echo " Check $1 Version => ${CONFIG_VERSION}" echo "" return 1 } pkgconfig_query_package() { echo " Search for $1" pkg-config --exists $1 if [ "$?" -ne "0" ] ; then echo " Unable to find a compatible $2 installation. Please make" echo " sure the correct version is installed including the header files." echo " You can use the \"--$2-prefix\" option to search in an" echo " alternative installation directory." return 0 fi PKG_VERSION=$(pkg-config --modversion $1 --print-errors --errors-to-stdout) PKG_PREFIX=$(pkg-config --variable=prefix $1) PKG_PREFIX=$(echo $PKG_PREFIX | tr -d '"') PKG_LDFLAGS=$(pkg-config --libs-only-L $1) PKG_LIBS=$(pkg-config --libs-only-l --libs-only-other $1) PKG_CFLAGS=$(pkg-config --cflags-only-other $1) PKG_CPPFLAGS=$(pkg-config --cflags-only-I $1) echo " Found $2 $PKG_VERSION in $PKG_PREFIX" echo "" return 1 } add_config_string() { echo "#define $1 \"${2}\"" >> $CFG } add_config() { DEF=$(echo $1 | tr '[:lower:]' '[:upper:]') echo "#define HAVE_${DEF}" >> $CFG OPTIONS="$OPTIONS $1 " } add_required_package() { pkgconfig_query_package "$1" "$2" if [ "$?" -eq "0" ] ; then exit -1 fi PACKAGES="$PACKAGES $1 " add_config "$2" return 1 } add_package() { pkgconfig_query_package "$1" "$2" if [ "$?" -eq "0" ] ; then return 0 fi PACKAGES="$PACKAGES $1 " add_config "$2" return 1 } # Check for the FOX library #-------------------------- check_reswrap() { # Configure Reswrap #------------------ echo " Checking Reswrap ... " COMMAND=${RESWRAP:-${PKG_PREFIX}/bin/reswrap} if [ ! -x $COMMAND ] ; then echo "Missing reswrap" exit 1 fi RESCMD=$(${COMMAND} -v 2>&1) RESVERSION=$(echo ${RESCMD} | cut -d" " -f2) RESWRAP_MAJOR=$(echo ${RESVERSION} | cut -d. -f1) if [ $RESWRAP_MAJOR = "5" ] ; then RESWRAP_H="${COMMAND} --keep-ext --header" RESWRAP_CPP="${COMMAND} --keep-ext --source --extern" RESWRAP_TEXT="${COMMAND} -t --keep-ext" else RESWRAP_H="${COMMAND} -i -k" RESWRAP_CPP="${COMMAND} -e -k" RESWRAP_TEXT="${COMMAND} -t -k" fi } check_foxversion() { PKG_MAJOR=$(echo "${PKG_VERSION}" | cut -d. -f1) PKG_MINOR=$(echo "${PKG_VERSION}" | cut -d. -f2) PKG_LEVEL=$(echo "${PKG_VERSION}" | cut -d. -f3) add_config "fox${PKG_MAJOR}${PKG_MINOR}" } gogglesmm-0.12.7/build/makemo0000644000175000001440000000041211134136514014574 0ustar sxjusers#------------------------------------------------------------------------------- # Make Mo's #------------------------------------------------------------------------------- for i in po/*.po do echo "Generating ${i%.po}.mo ..." msgfmt $i -o ${i%.po}.mo done gogglesmm-0.12.7/icons/0000755000175000001440000000000012007100617013412 5ustar sxjusersgogglesmm-0.12.7/icons/gogglesmm_16.png0000644000175000001440000000151511551136402016415 0ustar sxjusersPNG  IHDRabKGDIDAT8RKhTg=wG;30&JQh2ͣqa nEip )]DA/iER$MH%1'gΝǽwgw>|w8D0CfV8z"aQ@$ۛO6KuG3=wm$ۧl_sn?& <-꒯v/_ ̯"ʵjrz0o:̿ @)~)n..~&k*`8m, `c@`UƂgXZ6\w63`8mcYa,SlmۃJFL `?2<{%yh:VK6$Fs_\ks|D<*0Mܶ}:)q|h6 eK$ I}fC?|W5>>---___@@@XXXEEE %%%;;;666### ---+++ O$F ( $,am:x WS~}WiʞpIFd#¾ G|wP@-WSb`$?;&7I$kzMiJ?8xXTE7&HJMQy_CYsRrK ;S jMV7+o[BM^'NF@;lU;gH0*`_* -%˙c|U]J433-, TI 9+.*JVT 6D *yX'# ## A NR< *þd귁d%,7tRNSګ`5~Pl۔;LoԇXd{<pCN2( FMIDATx XSgijH$l%s]l:::VGQ筂eJ0RB0e)ck211ca Ǣs( z>yI0(3uw"s_,. K ?1yqaѣ>wL`p,|v54ǽE 83B"gXwm]xUI1b>?,AiyI]]]]gN(5UiwJ !?asuLXvJıgg߽,tEb 4iҬ&j4Xt 1]};-ghDPY%pqx`cMe=+%`|-.|4 lβIRǩAaRJ 6>+u!QBWxӗXSG{ z{A: u6bq?pAvsè$XxR1\D0Q2un0E?7.@\,` DUQӄG&+xoJ*:NYuM#h6rEDE?ƍby8٩Rт!_e߹kVֵ= /;f< FPҒܧ\(xu 1ݨ"|FiϼštEU^SBhbEM"R|\AcMKo][^\gf"`rKTFˆǗ}k'^DxN 4+xSd u/ 3&?#zjw*9>ȵzٞˡ uvr #i]bji)K}|E.VA?d6V&k(AY%\;!nTo/P$`6ĂJsLJ?s&gNu6+GeJlKe)̨ $*B(s+U6ѓJӓ͍}O`QkԳikzF3J[hd6`7bŤ2Լ ;'N0!t{yF(!mJb#%Jgt:vԸODdqȘX}{J'AP S/y;;!d5UBȖۗ]r(x,7#u:c~Lq@[1XXZ__o J=줴oP4~Tr.J¯M3Bl1A,VϵR(;).v{.aI<7&(.=ź-s13aXH,pUTAzyÎmmw J!H7~`+Km C',>dĴKPIX(S^v9&DH˗KV4ʄu=˕ߺՍp% 9mK`m(So`Za,\X@q7AX:FXA0<3RX` ]gK:SMĚlҴVLă oGI`(^ tߨqau[xN՝&[i== -<@3X7g]f$9În"©lX$ɇX/$E0 --Ze "H2A]c7 |嵙fPqjbj@ h5)؀J嵙X.K8LAL.1w0^ŚRԅ15SD^8¡Z=ϼ[ҧǘ_^đˆpCfA3 tW*]2ntE oYp+}Dit7uκ}$!٩\l|GXhkC4( ,\zM"_2=wزe ,=s++cuӂm橞m9~czMߋ.!Z6\bQH RQA5@i׋j*uꗕ>6b.N)5 zJ++*]`x7*SJs VbZӜa,Sn=igW{(Ql=7g sɠa7lFD6?ga6-cEs䉚UTWTT }BER)[]F3jFUgz -U(}f32S`v5#` Ѝ+U$D>B Ȩ+#j y֎3"b=6 j"A}Z~^1;q 28]q,1/3ZB 33D'OyѡQ@OOlknLfLTr{ڻ7r8ƌc(FZMl"k(bR)TGG׼Q)Se^Xrr}_Ndߖ$3uj>bdM) 7ttB\"ÇͮF=hzv&'U8 :$ꦙg>)Â"x5Jʀ& R%jZϔ bU3VgInq|cr2p仟{mZH ;}f6#.`Պ3B|NM%%JNֹ qsbk◕H݃vxkj^5) egP C09{\)IZ% LIl,Y!%(fxuеT.m.ǏHAv[zh뱡>5;`!r)QR IyyB?ѥ?0ɨ{:/ܕ`8&5JZHZZhъx)vwztQW?_|^{Օ`7|ի羲DܙxA+ [36-|"9Sa'c2ً/k/=x{E" XhnOESVX,=o~5""#FZY_?֓c 8FXKVf K#`Vn3LhA54GM{8 E:Y~LGѤnʹ"Ku|!~ݤ׈W-rT (ZtC~ 1R빯3Wm5p !VrѵQAɚ&Y㕸CPG6=zt YZAէV20/IQ^*LkdQ<:h;#)*c:;l,zvcb NVa ^ g4lёSN)Gb}2ƳW6"z@zZ)> [¢"B}'5TVTR=*MmXW={`M_Z+! :LJ.F }a&ϲ\,- d:-Mxy[^V] B[!fÝ1xNNR2k 2( Š-\Q2G2:}I^l[6BȠe: U .N Pܟ=[zT ]+,Xn1 gPUJ$WdYږ--1OIGpa]TdȀP_vD@ PuwoЍp`a4F7>:fEEL$'.,:LǧBpyfV) u,Ic@霨Dhb0=-濎 )lPlYG _27@(z.n |6Tlѳk­Hnٟ5IENDB`gogglesmm-0.12.7/icons/gogglesmm_32.png0000644000175000001440000000413511551136403016415 0ustar sxjusersPNG  IHDR szzbKGDIDATXWklTf޹{z6A!M %J$P"(i*D*H%i&BmFM( !0c k6{~JRIWWsΜ~gւ|=kW&V=CTwŭ_̞=i|jh3My(R1p-Y;u,T^}پC_gnpuOG/sɺ@ﱽ墵q|BQ*-Z0^ O{޶d-r-R*ErCT]o!.rG㏬YB}}AK ر[7,VxdX&oj6[/ ']yrLׁvֿ?,ژPN#kC3 M %I0F ?^gݵ_Q.9'Wɮ"m.LcEiPC?{@!&/8) "3TY&jn(e;K3U9y]ByK{|t~NYG5ӥrD]~d{ݩ̹[ (K+ LwaXzc@VU逬ă^yv^~mҖV6T.u7{ ^-! IwmJ%$U' &AwSLajIB򔃫EE֏K3Ϯ4H-YCp),#LO 0a[H@ j}x)Zw)}P@! zD t4h ~Qw? 28X]e;y!\-+$ 2}I;ZVMDOwWeRt}?@.*G_EwApSMs/!GOA*ԯx_dg#"R}/$l/q3!q;D8BQCD"kUcJkĎBl'Thh.ݸ:޶P0R+b]jQt-Cx 2#\v7ozʮjWD$;P W竚%Ödž!<HKT祹Z69R]2Xt7B*[ ۗ_PH|2o`QʟnRdrW_۞l76W`) tsGvX=]6\"2=gr 2؇>+l2S\Z?DHJg T02ǂn&Ы& Bjo--<@Cs Ψ7dWL)U;hRQJpȶs1pcnB9l3dg#cяg@ E?~Z *7żnHv㘃}2!ᕗs klh:7ǩp[ex'Σ,\<\YahW'X,m^3p\D>ް=?"f \-Z?w%Mx9ʗ>ϰl63 ΍xI21vܴIcǭ46MSUM@X7~#mpOl_2 u?Sّy{IENDB`gogglesmm-0.12.7/icons/cursor_hand.gif0000644000175000001440000000016011123027203016402 0ustar sxjusersGIF89a! ,A pZ/Een%XUԕ@*$}*.k!h2IsLj8FiO;gogglesmm-0.12.7/Makefile0000644000175000001440000001473311714632131013754 0ustar sxjusers#----------------------------------------------------------- # GOGGLES BUILD SYSTEM #----------------------------------------------------------- # # The actual make file # #----------------------------------------------------------- include config.make include build/version # Set suffixes .SUFFIXES: .SUFFIXES: .cpp .h .gif .png $(OBJEXT) $(BINEXT) $(LIBEXT) .PHONY : all clean realclean cleanicons install install-desktop INSTALL=install # Convert to Platform specific names #---------------------------------------------------------- BINNAME=src/gogglesmm$(BINEXT) # XXX on Linux, X.exe on Windows # Installation Directory ifdef DESTDIR INSTALL_DIR=$(DESTDIR)$(PREFIX) INSTALL_LOCALEDIR=$(DESTDIR)$(LOCALEDIR) INSTALL_MANDIR=$(DESTDIR)$(MANDIR) else INSTALL_DIR=$(PREFIX) INSTALL_LOCALEDIR=$(LOCALEDIR) INSTALL_MANDIR=$(MANDIR) endif all: $(BINNAME) TARNAME=gogglesmm-$(MAJOR).$(MINOR).$(LEVEL) ICONS := icons/cursor_hand.gif \ icons/about.png \ icons/gogglesmm_16.png \ icons/gogglesmm_32.png # Objects to Compile #---------------------------------------------------------- SRCFILES := src/fxext.cpp \ src/GMAbout.cpp \ src/GMAnimImage.cpp \ src/GMApp.cpp \ src/GMAudioScrobbler.cpp \ src/GMClipboard.cpp \ src/GMColumnDialog.cpp \ src/GMDatabase.cpp \ src/GMDatabaseSource.cpp \ src/GMFetch.cpp \ src/GMFilename.cpp \ src/GMFontDialog.cpp \ src/GMImageView.cpp \ src/GMEQDialog.cpp \ src/GMIconTheme.cpp \ src/GMImportDialog.cpp \ src/GMList.cpp \ src/GMPlayer.cpp \ src/GMPlayerManager.cpp \ src/GMPlayListSource.cpp \ src/GMPreferences.cpp \ src/GMPreferencesDialog.cpp \ src/GMQuery.cpp \ src/GMRemote.cpp \ src/GMSearch.cpp \ src/GMSource.cpp \ src/GMSourceView.cpp \ src/GMTag.cpp \ src/GMThread.cpp \ src/GMTrackDatabase.cpp \ src/GMTrackList.cpp \ src/GMTrackItem.cpp \ src/GMTrackView.cpp \ src/GMTrayIcon.cpp \ src/GMStreamSource.cpp \ src/GMURL.cpp \ src/GMWindow.cpp \ src/main.cpp \ src/gmutils.cpp \ src/ap_buffer.cpp \ src/ap_http.cpp \ src/ap_xml_parser.cpp \ src/icons.cpp ifneq (,$(findstring md5,$(OPTIONS))) SRCFILES += src/md5.cpp endif ifneq (,$(findstring fox16,$(OPTIONS))) SRCFILES += src/GMMessageChannel.cpp endif ifneq (,$(findstring dbus,$(OPTIONS))) SRCFILES += src/GMDBus.cpp \ src/GMNotifyDaemon.cpp \ src/GMMediaPlayerService.cpp \ src/GMSettingsDaemon.cpp endif OBJECTS := $(patsubst %.cpp,%$(OBJEXT),$(SRCFILES)) DEPENDENCIES = $(patsubst %.cpp,%.d,$(SRCFILES)) $(BINNAME): $(OBJECTS) @echo " Linking $@ ..." # @echo "$(LINK) $(LDFLAGS) $(OUTPUTBIN)$(BINNAME) $(OBJECTS) $(LIBS)" @$(LINK) $(LDFLAGS) $(OUTPUTBIN)$(BINNAME) $(OBJECTS) $(LIBS) %$(OBJEXT): %.cpp @echo " Compiling $< ..." # @echo "$(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) -MM -o $*.d -MT $@ $<" @$(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) -MM -o $*.d -MT $@ $< # @echo "$(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) $(OUTPUTOBJ)$@ -c $<" @$(CXX) $(CFLAGS) $(DEFS) $(CPPFLAGS) $(OUTPUTOBJ)$@ -c $< ifneq (,$(findstring dbus,$(OPTIONS))) src/gogglesmm_xml.h: src/gogglesmm.xml @echo " Creating src/gogglesmm_xml.h..." @$(RESWRAP_TEXT) -o $@ src/gogglesmm.xml src/mpris_xml.h: src/mpris_root.xml src/mpris_player.xml src/mpris_tracklist.xml @echo " Creating src/mpris_xml.h..." @$(RESWRAP_TEXT) -o $@ src/mpris_root.xml src/mpris_player.xml src/mpris_tracklist.xml endif $(OBJECTS): src/icons.h src/icons.cpp src/icons.h: $(ICONS) @echo " Creating Icon Resource Header" @$(RESWRAP_H) -o $@ $(ICONS) src/icons.cpp: $(ICONS) @echo " Creating Icon Resources" @$(RESWRAP_CPP) -o $@ $(ICONS) ifneq (,$(findstring dbus,$(OPTIONS))) src/GMPlayerManager.cpp: src/gogglesmm_xml.h src/GMMediaPlayerService.cpp: src/mpris_xml.h endif TRANSLATIONS:=$(basename $(notdir $(wildcard po/*.mo))) LINGUAS?=$(TRANSLATIONS) # Install #---------------------------------------------------------- install: $(BINNAME) @echo " Installing $(INSTALL_DIR)/bin/gogglesmm ..." @$(INSTALL) -m 755 -D src/gogglesmm $(INSTALL_DIR)/bin/gogglesmm @echo " Installing $(INSTALL_DIR)/share/applications/gogglesmm.desktop" @$(INSTALL) -m 644 -D extra/gogglesmm.desktop $(INSTALL_DIR)/share/applications/gogglesmm.desktop @echo " Installing Icons" $(INSTALL) -m 644 -D icons/gogglesmm_16.png $(INSTALL_DIR)/share/icons/hicolor/16x16/apps/gogglesmm.png $(INSTALL) -m 644 -D extra/gogglesmm_22.png $(INSTALL_DIR)/share/icons/hicolor/22x22/apps/gogglesmm.png $(INSTALL) -m 644 -D extra/gogglesmm_24.png $(INSTALL_DIR)/share/icons/hicolor/24x24/apps/gogglesmm.png $(INSTALL) -m 644 -D icons/gogglesmm_32.png $(INSTALL_DIR)/share/icons/hicolor/32x32/apps/gogglesmm.png $(INSTALL) -m 644 -D extra/gogglesmm_48.png $(INSTALL_DIR)/share/icons/hicolor/48x48/apps/gogglesmm.png $(INSTALL) -m 644 -D extra/gogglesmm.svg $(INSTALL_DIR)/share/icons/hicolor/scalable/apps/gogglesmm.svg @echo " Installing $(INSTALL_MANDIR)/man1/gogglesmm.1" @$(INSTALL) -m 644 -D extra/gogglesmm.1 $(INSTALL_MANDIR)/man1/gogglesmm.1 ifneq (,$(findstring nls,$(OPTIONS))) @echo " Installing Translations" @linguas='$(filter $(TRANSLATIONS),$(LINGUAS))'; \ for tr in $$linguas ; do \ echo " Installing $(INSTALL_LOCALEDIR)/$$tr/LC_MESSAGES/gogglesmm.mo" ;\ $(INSTALL) -m 644 -D po/$$tr.mo -T $(INSTALL_LOCALEDIR)/$$tr/LC_MESSAGES/gogglesmm.mo ; \ done; endif # Clean #---------------------------------------------------------- clean : @echo " Remove Executables ..." @rm -f $(BINNAME) @echo " Remove Objects ..." @rm -f src/*$(OBJEXT) @rm -f src/*.d @echo " Remove Generated Files ..." @rm -f src/icons.cpp @rm -f src/icons.h @rm -f src/gogglesmm_xml.h @rm -f src/mpris_xml.h #---------------------------------------------------------- realclean : @echo " Remove Configuration ..." @rm -f config.make @rm -f src/gmconfig.h dist: clean realclean sh build/makemo rm po/fi.mo rsvg-convert -w 22 extra/gogglesmm.svg -o extra/gogglesmm_22.png rsvg-convert -w 24 extra/gogglesmm.svg -o extra/gogglesmm_24.png rsvg-convert -w 48 extra/gogglesmm.svg -o extra/gogglesmm_48.png @echo " Creating Tarbals .." tar --create --xz --file='../../$(TARNAME).tar.xz' --verbose --exclude-vcs --exclude='*.tar.xz' --transform='s/^./$(TARNAME)/' --show-transformed-names . tar --create --bzip2 --file='../../$(TARNAME).tar.bz2' --verbose --exclude-vcs --exclude='*.tar.bz2' --transform='s/^./$(TARNAME)/' --show-transformed-names . # Clean Icons #---------------------------------------------------------- cleanicons : @rm -f src/icons.* @rm -f src/icons.* #---------------------------------------------------------- # How to make everything else -include $(DEPENDENCIES) gogglesmm-0.12.7/AUTHORS0000644000175000001440000000242611643051412013356 0ustar sxjusersGoggles Music Manager Copyright (C) 2002-2011 by Sander Jansen. All Rights Reserved. Various code snippets from FOX-Toolkit Copyright (c) 1998-2011 by Jeroen van der Zijp. All Rights Reserved. Translations ------------ Hendrik Rittich (German) Víctor Pérez Masegosa (Spanish) Erwan Inyzant (French) Sándor Sipos (Hungarian) L Lawliet (Russian) David Vachulka (Czech) Christian Hellberg (Finnish) Sérgio Marques (Portugese) Other Contributions ------------------- - Original "Goggles" logo designed by Gyurka Jansen. (http://glas.its.tudelft.nl/~gyurka) - Contains icons from Tango and Gnome icon themes. - MD5 implementation see: src/md5.cpp Thanks for all the Fish! ------------------------ - Thanks to Charles Warren and Jeroen van der Zijp for testing and many useful suggestions. - Thanks to Oktay Cetinkaya for feedback and bugreports. - Thanks to Gyurka Jansen for the Goggles Logo!. - Thanks to Jason Donenfeld for the many useful suggestions and bug reports. - Thanks to Oliver Duclos for the first tray icon implementation and the usefull bug reports. - Thanks to Sascha Klauder for FreeBSD porting. - Thanks to Chadi El Ahmad for the SliTaz package. - Thanks to John Tyree for feedback and bugreports. - Thanks to Andrey Yurchuk for the Gentoo ebuild. gogglesmm-0.12.7/po/0000755000175000001440000000000012063217122012717 5ustar sxjusersgogglesmm-0.12.7/po/de.mo0000644000175000001440000011205212063217121013644 0ustar sxjusersw|X'Y'(v'''+''-(04(1e(5(( (!())=)O)W)^)d)v)1)5)-).*K*j**zV+7+ ,,,#, *,4,3;,o,"w,,!,,,!,- - ,- 7- C-O-U- ]-i-r-{-- - --K-9-..5.;.?.'C.k.q."w... ......*./'/-/3/ J/W/ ]/j/p/w/}//F/ // / /B/@0H0 a0o0 ~0 0000*1-1-2=2CD22 22 2222 3 3 332373>3E3 K3Y3v3 33<33344$4 ,464H44\4'4 4+444 5 5=5E5L5R51a555 5 5 55 55 566"6 96E6 a6o66 6"6 66 6 6 66677-7"?7b7Ci777 77 777 8283O8'828 8)8 9 94,9a9%q9999%99"9::;'; -;:;!< '<4<H<W<\< b<n<=< <8<="===L=]= m= y== == =+=== = ==>> #>1> F>OT> > >>+>> >??!?8?)S? }?&?+?? ?? @%@ 6@&A@ h@Ws@@@@ @@AAA/A @AJAYA jAtAzAAAA"AAABB-B#GBkB sBB9B BBBB1B'C&6C]CcC hC uC CCC C5CCC D D.,D![D}DD)DDD+E&2E(YE'E)EE E. F&_I_Q_ X_!b_ _]_B_2` 9`D`J`2N```%`` `` ` `` aaFa^awa a aaaaaaaaaca bblbrb bSbbb cc %c 3c>cEcEWc=dAd@e ^e[he e eee&e'#fKf\fkf sfffffff/fg g)g`1ggg"ggggg hD"h<gh hh hhh*i;iCiUi[iEli iii ii j &j3j ;j HjTj+Yj jjj!j jj3k 5k@k Gk Qk ]khkokk/k k*k &lG3l {lllllllm7m;Jm(m7mm=m4n Kn=Ynn-nn nn. o9o"Boeomopp p1pqqqr+r4r!QkyY6\q1AiB9+n\$J[s* bG;?po{a?73|IteS{^1=Xz:,(%Hx}. t@~2`,4 Uc4R-u>_0Pf% 5Cc=AS~!<VGZ [D TW:3d)u}zF@f)MYOQI'Fy.w- _RNZ&p +Cg #(wbJ5eW9xP/X rmjLa0$!'^Nq]kDHr`hK6Uis#*EK;8|]jmdgT <8/MnBLl7voEh Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Track&View&Window&YesA DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAn incompatible (future) version of the database was found. This usually happens when you try to downgrade to a older version of GMM Press OK to continue and reset the database (all information will be lost!). Press Cancel to quit now and leave the database as is.Are you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBookmarksBorder Border ColorBothBottomBrowseBy %sCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.ColorsColumnsCondensedConfigure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Failed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:For some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport new tracks Imports files not yet in the database.Importing Files...Information… Library StatisticsInternet RadioInvalid TemplateKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMedium imagesMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesOffOops. Database ErrorOptions:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseRowsS&earch for:SamplerateSaturation:Security WarningSelect Normal FontSelect allSelected Selected Text ColorSession Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.This version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTooltip Tooltip ColorTopTotal Time:TrackTracks:Turn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.Project-Id-Version: gogglesmm 0.10.0 Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2009-07-06 09:41-0600 Last-Translator: Sander Jansen Language-Team: German Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); Lautstärke einstellen Lautstärke einstellen Lesezeichen Zu einem Lesezeichen wechseln. Nach Name Filter schließen Filter schließen Neues Verzeichnis erstellen Erstelle ein neues Verzeichnis. Zyan, Magenta, Gelb Zum Heimverzeichnis Zurück ins Heimverzeichnis. Zum Arbeitsverzeichnis Zurück zum Arbeitsverzeichnis. Eine Ebene nach oben Wechsele in ein höheres Verzeichnis. Verstecke versteckte Dateien Zeige keine versteckten Dateien und Verzeichnisse an. Farbton, Sättigung, Wert Farbe wählen Nächsten Titel wiedergeben Nächsten Titel wiedergeben. Vorherigen Titel wiedergeben Vorherigen Titel wiedergeben. Rot, Grün, Blau Entfernen Zurücksetzen Speichern Künstler aufteilen Künstler teilen Detailansicht Das Verzeichnis detailiert anzeigen. Versteckte Dateien anzeigen Zeige versteckte Dateien und Verzeichnisse an. Symbolansicht Das Verzeichnis mit großen Symbolen anzeigen. Listenansicht Das Verzeichnis mit kleinen Symbolen anzeigen. Wiedergabe starten Wiedergabe starten Wiedergabe anhalten Wiedergabe anhalten%T - Titelname %A - Albumname %P - Künstlername des Albums %p - Künstlername des Titels %y - Jahr %d - Disc-Nummer %N - Titelnummer (2 stellig) %n - Titelnummer %G - Genre%T - Titelname %A - Albumname %P - Künstlername des Albums %p - Künstlername des Titels %N - Titelnummer %G - Genre%s Bitte wenden Sie sich an den Support, falls dieser Fehler öfter auftritt.Ü&berÜber&nehmen&Alpha:&Audio&Rückwärts&Blau:&Browser anzeigen Ctrl-B Zeige den Künstler- und Alben-Browser.A&bbrechenLesezeichen leeren Entferne alle Lesezeichen.S&chließen&Spalten Ändere die Spalten.Spalten &konfigurieren&Steuerung&Kopieren Ctrl-C Die ausgewählten Titel kopieren&ErstellenAuss&chneiden Ctrl-X Die ausgewählten Titel ausschneiden&VerzeichnisVer&zeichnis&Nicht SpeichernB&earbeiten&Exportieren&Dateiname:&Dateien&Allgemein&Grün:&Hilfe&HomepageGroß-/Kleinschreibung ignorieren&ImportierenGMM auf last.fm b&eitreten… Treten Sie der Goggles Music Manager-Gruppe auf last.fm bei…Zum aktuellen Titel &springen Ctrl-J Zeige den aktuellen Titel an.&Musik&Nächster&Nein&OKE&infügen Ctrl-V Aus der Zwischenablage einfügen&PlayB&eendenB&eenden Ctrl-Q Beende die Anwendung.&Rot:&Entfernen&Entferne AlleUm&benennenE&rsetzenEinen Fehle&r melden…&Speichern&SuchenLe&sezeichen erstellen Lege ein Lesezeichen ins aktuelle Verzeichnis.Bei last.fm &anmelden…Über&springen&Sortierung&Sortierung Sortierung ändern.Die Uhr &starten&StoppImport &stoppen&Sync&Titel&Ansicht&Fenster&JaDBus hat einen Fehler verursacht. Alle Funktionen, die DBus benötigen stehen nicht zur Verfügung.&AussehenAlbumKünstlername des AlbumsAlbencoverAlben Klicken, um die Reihenfolge zu ändern Klicken, um die Reihenfolge zu ändernAlben:Alle Lies alle TagsAlle %d AlbenAlle %d KünstlerAlle %d GenreAlle GenreAlpha:Existiert bereitsEs wurde eine inkompatible (neuere) Version der Datenbank gefunden. Dieser Fehler tritt beim Verwenden einer älteren GMM Version auf. Drücken Sie OK um fortzufahren. Dabei wird die Datenbank zrückgesetzt und alle zuvor gespeicherten Informationen verworfen! Drücken Sie Abbrechen um die Datenbank unverändert zu lassen.Sind Sie sicher, dass Sie die Einstellung %s löschen wollen?Sind Sie sicher, dass Sie die folgende Datei löschen wollen: %sSind Sie sicher, dass Sie diese Wiedergabeliste löschen wollen?KünstlerKünstlername Klicken, um die Reihenfolge zu ändern Klicken, um die Reihenfolge zu ändernKünstler:AttributeAudio-Gerät-FehlerAudio-Treiber:Die Audioausgabe ist nicht verfügbar.Automatische Titelnummer. Erste Nummer:Basis BasisfarbeGroße SymboleBitrateLesezeichenRahmen RahmenfarbeBeidesUntenBrowser anzeigenNach %sKann nicht erstellt werdenDas Verzeichnis %s kann nicht erstellt werden. Wiedergabeliste umbenennenÄndern…KanäleBitte wählen Sie die Reihenfolge, in der die Informationen in der Titelliste erscheinen sollen.Musikbibliothek leeren?Lesezeichen leerenBei Pausen Audio-Gerät freigeben.FarbenSpaltendünnSpalten konfigurierenVerbindung abgewiesen.Kopieren Ctrl-C Kopiere die zugehörigen Titel in die ZwischenablageKopieren Ctrl-C Kopiere die/den Titel in die Zwischenablage.Kopiere DateiKopiere Datei von: %s nach: Kopieren...Neues Verzeichnis anlegenErstelle WiedergabelisteErstelle neues Verzeichnis mit dem Namen: AktuellBenutzerdefiniertZyan:Datenbank-FehlerDatenbank-Fehler: Die Dateinamen konnten leider nicht gelesen werden.Standardwert:Wiedergabeliste löschen?Voreinstellung löschenLöschen...Datei löschenDateien werden gelöschtBeschreibungDetailsVerzeichnis:DeaktiviertDiscAktuellen Titel in der Titelleiste anzeigenAusdrückeBearbeite RadiosenderWiedergabeliste bearbeitenBearbeite die Titel-InformationenBearbeiten…Bearbeiten… Bearbeiten… F2 Bearbeite die Titel-Informationen.Kodierung:EngineEqualizerEqualizer Equalizer:FehlerFehler während des KopierensFehler während dem LöschenFehler während der Erstellung der VerknüpfungFehler während des VerschiebensFehler beim Laden einer Bibliothek/PluginsExtr&ahierenAusfiltern Filtere Verzeichnisse und/oder Dateien nach einem Muster ausAusnahmen:BreitAlbum exportierenKünstler exportierenGenre exportierenExportiere die HauptbibliothekExportiere WiedergabelisteTitel exportierenExportiere die Titel dieses Albums ins Zielverzeichnis.Exportiere die Titel dieses Künstlers ins Zielverzeichnis.Exportiere die Titel ins ZielverzeichnisExportiere die Titel diesen Genres ins Zielverzeichnis.Exportieren…Der angeforderte Audiotreiber konnte nicht geladen werden: %sSchwerwiegender FehlerDateif&ilter:Die Datei existiert bereits. Möchten Sie sie überschreiben?Datei wurde nicht gefunden.Datei oder Verzeichnis %s existiert bereits. Datei:DateinameVorlage für DateinamenFür die Dateinamen war keine Änderung nötigDateien:Suchen… Ctrl-F Zeige Suchfilter.Ordner:Das FOX-Toolkit wurde ohne PNG-Unterstützung kompiliert. Diese wird allerdings benötigt, damit Goggles Music Manager alle Symbole anzeigen kann. Wenn Sie das FOX-Toolkit selber kompiliert haben, so waren die libpng Header-Dateien wahrscheinlich nicht auf Ihrem System vorhanden.Lückenlose WiedergabeGenreGroße BilderGoogle Music Manager konnte die Datenbank nicht öffnen. Die Datenbank wurde möglicherweise beschädigt. Bitte entfernen Sie die Datei ~/.goggles/goggles.db und versuchen Sie es erneut. Sollte der Fehler weiterhin bestehen, senden Sie bitte einen Fehlerbericht auf http://code.google.com/p/gogglesmm ein.GruppeVersteckte DateienHilite Farbe von MarkierungenHeimverzeichnisFarbton:SymboleGroß-/Kleinschreibung ignorierenFührende Worte ignorierenOrdner &importieren… Ctrl-O Importiere die Musik aus einem Ordner in die BibliothekMusik importierenNeue Titel imporieren Titel, die sich noch nicht in der Datenbank befinden, werden importiert.Dateien werden importiert...Informationen… BibliotheksstatistikInternet-RadioUngültige VorlageWiedergabelisten behaltenGroße SymboleLast.FM-FehlerLast.fmFehler in der BibliothekVerknüpfungVerknüpfung erstellenErstelle Verknüpfung %s mit: Verknüpfung erstellen...OrtOrt:KleinschreibungKlein geschriebene Datei-ErweiterungMagenta:ManuellMittelgroße BilderMenü Farbe des MenüsÄnderungsdatumZuletzt geänderte Dateien Lies nur tag aus geänderten DateienNach unten verschiebenVerschiebe DateiNach oben verschiebenVerschiebe Datei von: %s nach: Verschieben...MusikbibliothekMusikbibliothek-InformationenNameKeine Verbindung zum Netzwerk.Neuer InternetradiosenderNeue Wiedergabeliste… Erstelle eine neue WiedergabelisteNeue WiedergabelisteNeue &Wiedergabeliste… Erstelle eine neue WiedergabelisteNeuer &Radiosender… Trage einen neuen Radiosender einNeuer Radiosender Neue Titel:Neues Verzeichnis...NächstesNächsten Nächsten Titel wiedergeben Nächsten Titel wiedergebenNächsten TitelNächsten Titel Ctrl-] Gib den nächsten Titel wieder.Keine ÄnderungenKeine Titel wurden aktualisiert. Möchten Sie immer noch die Tags für die ausgewählten Titel in die Datei schreiben?Nr.NormalNormal Normale TextfarbeNormalgroße BilderAusOh je. Ein Datenbank-FehlerOptionen:Datei überschreiben?Voreinstellung überschreiben&VorherigerEinstellungen lesenLies die Informationen aus:Passwort:PausePause Pause Die Wiedergabe pausierenDie Wiedergabe pausieren.PlayPlay Ctrl-P Starte die Wiedergabe.Play Starte die Wiedergabe Starte die WiedergabeWiedergabeWiedergabe-FehlerPlayer-SteuerungSpielend Farbe des aktuellen TitelsBitte geben Sie den Namen der Voreinstellung ein:Bitte warten Sie einen Moment.VorverstärkerEinstellungenEinstellungen…Die Einstellung %s existiert bereits. Möchten Sie sie überschreiben?Name der VoreinstellungVoreinstellungen:VorschaubildVorherigesVorherigen Vorherigen Titel wiedergeben Vorherigen Titel wiedergebenVorherigen TitelVorherigen Titel Ctrl-[ Gib den vorherigen Titel wieder.WarteschlangeBeendenAlle Erset&zenLesefehlerSchreibgeschütztBereit.Entfernen EntfernenAlbum entfernen?Alle Titel entfernen Entferne alle Titel aus der BibliothekKünstler entfernen?Audio-Dateien werden entfernt...Audio-Dateien entfernen?Genre entfernen?Radiosender aus der Bibliothek entfernen?Radiosender entfernen?Entferne WiedergabelisteTitel entfernen?Alle Titel aus der Musikbibliothek entfernen?Die/Den Titel aus der Bibliothek entfernen?Entferne die/den Titel aus der Wiedergabeliste?Entferne alle Titel in diesem Ordner aus der DatenbankEntferne die Titel dieses Albums aus der Bibliothek.Entferne die Titel dieses Albums aus der Wiedergabeliste?Entferne die Titel dieses Künstlers aus der Bibliothek.Entferne die Titel dieses Künstlers aus der Wiedergabeliste?Entferne die Titel von der FestplatteEntferne Titel aus der MusikbibliothekEntferne von der Festplatte gelösche TitelEntferne die Titel dieses Genres aus der Bibliothek.Entferne die Titel dieses Genres aus der Wiedergabeliste?Löschen… Del Das Genre aus der Bibliothek löschen.Löschen… Del Lösche die zugehörigen Titel aus der BibliothekLöschen… Del Lösche die/den Titel aus der Bibliothek.Entfernen… Del Entferne die/den Titel aus der Wiedergabeliste.Audio-Dateien umbenennen?Die Audio-Dateien werden umbenannt…Wiederhole AWiederhole A-BWiederholung A-B Ctrl-T Wiederhole die Titel, die sich zwischen zwei ausgewählten Titeln befindenWiederhole alle Titel Ctrl-/ Wiederhole alle Titel.Wiederholung aus Ctrl-, Wiederhole den aktuellen Titel.Wiederholung Ctrl-. Wiederhole den aktuellen Titel.Ersetzen &mit:Ersetze Leerzeichen durch UnterstricheErsetze Unterstriche durch LeerzeichenVerstärkung:Kein Zugriff auf die Ressource. Überprüfen Sie die Berechtigungen.RückwärtsZeilenSuch&en nach:SampelrateSättigung:SicherheitswarnungWähle normale SchriftartAlles AuswählenAusgewählt Farbe von ausgewähltem TextDer Session-Bus wurde nicht gefunden. Alle Funktionen, die DBus benötigen stehen nicht zur Verfügung.Der Session-Bus wurde nicht gefunden. Alle Funktionen, die DBus benötigen stehen nicht zur Verfügung.Lesezeichen erstellenWähle Export-Vorlage…Wähle die Titelnummer auf Grund der ScannreihenfolgeEinstellung der ZeitschaltuhrSchatten Farbe von Schatten&Genre anzeigen Ctrl-G Zeige den Genre-Browser.&Quellen anzeigen Ctrl-S Quellen-Browser anzeigen Browser anzeigenVollbild F12 Vollbildmodus umschaltenZeige Symbole im Titel-BrowserBeschriftungen anzeigenZeige die StatusleisteBei Titelwechsel benachrichtigen Informiere in der Systemleiste über Titelwechsel.Systemleistensymbol anzeigen Zeige ein Symbol in der Systemleiste an.Albumcover des abzuspielenden Titels anzeigen Albumcover des abzuspielenden Titels anzeigenAlbumcover im Albenbrowser anzeigen Albumcover im Albenbrowser anzeigenZufällige Wiedergabe Ctrl-RZufällige Wiedergabe Alt-R Gib die Titel in eine zufälligen Reihenfolge wiederGröße&Alle ÜberspringenZeitschaltuhrZeitschaltuhr Die Zeitschaltuhr einstellen.Stoppe inKleine SymboleSortierungsoptionenSortieren nachSortiere nach ErscheinungsjahrSortierungQuellen Klicken, um die Reihenfolge zu ändern Klicken, um die Reihenfolge zu ändernGeben Sie den Name der Wiedergabeliste einGeben Sie die URL und eine Beschreibung des Senders einStarte die Wiedergabe.SenderStopStopp Ctrl-\ Die Wiedergabe anhalten.Stopp Die Wiedergabe anhalten Die Wiedergabe anhaltenDie Wiedergabe nach einen bestimmten Zeit anhaltenStil:Ordner &synchronisieren… Synchronisiere die Ordner mit der BibliothekSync OperationOrdner synchronisierenSystemleisteTagDie Vorlage darf einen absoluten oder relativen Pfad enthalten, Umgebungsvariablen und ~. Relative Pfadangaben beziehen sich auf den ursprünglichen Ort der Datei. Die Datei-Erweiterung wird automatisch ergänzt. Die folgenden Macros dürfen benutzt werden:Vorlage:Die folgenden Audio-Dateien werden entferntDie folgenden Audio-Dateien werden umbenanntDie eingegebene Vorlage ist leider ungültig. Der Name des Titels %%T muss angegeben werden. Bitte korrigieren Sie die Vorlage für Dateinamen im Einstellungs-Dialog.Diese Version von Goggles Music Manager wird nicht von Last-FM unterstützt. Bitte aktualisieren Sie GMM.ZeitTitelnameKurzinfo Farbe von KurzinfosObenZeit insgesamt:TitelTitel:Beim Stoppen die Wiedergabe-Engine abschalten.Starte die Wiedergabe-Engine beim Programmstart. Um einen schnelleren Programmstart zu ermöglichen wird die Wiedergabe-Engine erst gestartet, wenn der erste Titel wiedergegeben wird Um einen schnelleren Programmstart zu ermöglichen wird die Wiedergabe-Engine erst gestartet, wenn der erste Titel wiedergegeben wirdTypKonnte die Datei nicht von: %s nach: %s kopieren. Trotzdem fortfahren?Das Verzeichnis %s kann nicht erstellt werden. Die Datei: %s konnte nicht gelöscht werden. Trotzdem fortfahren?Der Audiotreiber konnte nicht geladen werden.Der Titel konnte nicht in die Datenbank eingetragen werdenEs konnte kein Webbrowser gestartet werdenKonnte keine Verknüpfung %s mit: %s erstellen. Trotzdem fortfahren?Konnte die Datei nicht von: %s nach: %s verschieben. Trotzdem fortfahren?Die Datenbank konnte leider nicht geöffnet werdenDas Album konnte nicht aus der Bibliothek gelöscht werden.Der Künstler konnte nicht aus der Bibliothek gelöscht werden.Das Genre konnte nicht aus der Bibliothek gelöscht werden.Der Sender konnte nicht aus der Bibliothek gelöscht werden.Der Titel konnte nicht aus der Bibliothek gelöscht werden.Umbenennen der Datei nicht möglichUmbenennen der Datei nicht möglich: %s in:%sKonnte die Datei nicht umbenennen: %s in:%s Trotzdem fortfahren?Der Titel konnte nicht aktualisiert werdenUnbekannter FehlerUnbekanntes Gerät.Unbekannter host.UnbenanntEine Ebene nach obenDateiname aktualisierenAktualisiere den Tag in der DateiTags aktualisieren?Aktualisiere die bestehenden Titel:Aktualisiere die URL und Beschreibung des SendersDie Datenbank wird aktualisiert...BenutzerBenutzername:Wert:AnsichtLautstärke angleichenWarnungFensterArbeitsverzeichnisJahrGelb:Ihre Musiksammlung besteht aus…alt bg Alternative Hintergrundfarbebg Hintergrundfarbefg VordergrundfarbeStunden undMinuten.gogglesmm-0.12.7/po/fi.po0000644000175000001440000014266611524673460013710 0ustar sxjusers# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.0\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2010-07-27 21:17+0200\n" "Last-Translator: Christian Hellberg \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Sulje" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Säädä sarakkeet" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Hyväksy" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Peruuta" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Siirrä ylös" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Siirrä alas" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Virheellinen malli" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Tietokantavirhe" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Oho. Ilmeni tietokantavirhe." #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Ei muutoksia" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Nimetäänkö äänitiedostot uudelleen?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Nimetään uudelleen äänitiedostoja..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "&Nimeä uudelleen" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Ei voida nimetä uudelleen." #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Tiedoston nimi -malli" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Malli:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Koodaus:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Vaihtoehdot:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "Ei." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Otsikko" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Artisti" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Artistin albumi" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Albumi" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Levy" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Laji" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Vuosi" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Aika" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "" #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "" #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "" #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "" #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "" #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "" #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "" #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Vie..." #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Muokkaa raidan tietoja" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Tallenna" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Ominaisuudet" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Tiedoston nimi" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Tyyppi" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Koko" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Bittinopeus" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Kanavat" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Raita" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tErottele artistit" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tJaetut artistit" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Päivitä tiedoston avainsana" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Päivitä tiedoston nimi" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Aseta tuontimalli..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Päivitetäänkö avainsanat?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Poistetaanko äänitiedosto?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Poista äänitiedostot..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Poista" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Tuo pääkirjasto" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Tuo soittolista" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Ylikirjoitetaanko tiedosto?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Vie laji" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Vie artistit" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Vie albumit" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Vie raidat" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Vie" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Poistetaanko laji?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Poistetaanko artisti?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Kirjastovirhe" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "" #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "" #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Luo" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Poista kaikki" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "" #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Artistit:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tPoista" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "" #: src/GMFontDialog.cpp:209 msgid "Ultra Condensed" msgstr "" #: src/GMFontDialog.cpp:210 msgid "Extra Condensed" msgstr "" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "" #: src/GMFontDialog.cpp:212 msgid "Semi Condensed" msgstr "" #: src/GMFontDialog.cpp:214 msgid "Semi Expanded" msgstr "" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "" #: src/GMFontDialog.cpp:216 msgid "Extra Expanded" msgstr "" #: src/GMFontDialog.cpp:217 msgid "Ultra Expanded" msgstr "" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 msgid "Extra Light" msgstr "" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 msgid "Light" msgstr "" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 #, fuzzy msgid "Medium" msgstr "Keskikokoiset kuvat" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 msgid "Demibold" msgstr "" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 msgid "Extra Bold" msgstr "" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 msgid "Heavy" msgstr "" #: src/GMFontDialog.cpp:239 msgid "Reverse Oblique" msgstr "" #: src/GMFontDialog.cpp:240 msgid "Reverse Italic" msgstr "" #: src/GMFontDialog.cpp:242 msgid "Italic" msgstr "" #: src/GMFontDialog.cpp:243 msgid "Oblique" msgstr "" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "&Hakemisto:" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&Tiedoston nimi:" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Vain luku" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "" #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "" #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "" #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "" #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "" #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "" #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "" #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "" #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "" #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "" #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "" #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "" #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Tiedosto(t)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Hakemisto" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Raita" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Aivainsana" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "" #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Tuo" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "" #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "" #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "" #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "" #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "" #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "" #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "" #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "" #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Kyllä" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Ei" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Yleinen" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "" #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 #, fuzzy msgid "&Sign up…" msgstr "&Rekisteröidy last.fm-palveluun…" #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Ikkuna" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "" #: src/GMPreferencesDialog.cpp:365 msgid "Close button minimizes to tray" msgstr "" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "U&lkoasu" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:433 msgid "Menu\tMenu Base Color" msgstr "" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 msgid "Default Font" msgstr "" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "" #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Ääni" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "" #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "" #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Seuraava" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "E&dellinen" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Toista" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Pysäytä" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "" #: src/GMRemote.cpp:385 msgid "\tShow Browser\tShow Browser" msgstr "" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "" #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "" #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "" #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "" #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "" #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "" #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "&Pysäytä tuonti" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "" #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "L&uo" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "" #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "" #: src/GMTrackView.cpp:246 msgid "&Find" msgstr "" #: src/GMTrackView.cpp:252 msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Säädä sarakkeita…" #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Kaikki %d lajit" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Kaikki lajit" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Kaikki %d artistit" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "" #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "" #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Edellinen raita" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Seuraava raita" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "" #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "" #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Musiikki" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "" #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "&Muokkaa" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "" #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Näytä" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "" #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "" #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "" #: src/GMWindow.cpp:296 msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "" #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Järjestä" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "" #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Hallitse" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "" #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "" #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "" #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "" #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "" #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "" #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "" #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "" #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "" #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "" #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Ohje" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Kotisivu" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "&Ilmoita ongelmasta…" #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Rekisteröidy last.fm-palveluun…" #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&Tietoja…" #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Edellinen" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Seuraava" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "" #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 msgid "Start playback" msgstr "" #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "" #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "" #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "" #: src/GMWindow.cpp:1206 msgid "…" msgstr "" #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Aloita ajastin" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "" #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Poistu" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Ohita" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Ohita &kaikki" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Älä tallenna" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Punainen:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Vihreä:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Sininen:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "On jo olemassa" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Ei voida luoda" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Kopioi tiedosto" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Kopioi..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Siirrä..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Poista..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Muokkauspäivä" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Käyttäjä" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Ryhmä" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Valitse kaikki" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "järjestä:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "näytä" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Pienet kuvakkeet" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Isot kuvakkeet" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Tiedot" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Rivit" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Sarakkeet" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 #, fuzzy msgid "Preview images" msgstr "Esikatselukuvat" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Tavalliset kuvat" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Keskikokoiset kuvat" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Suure kuvat" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Korvaa" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Ko&rvaa kaikki" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "E&tsi:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "&Korvaa:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Etsi" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Valmis." #~ msgid "Old Name" #~ msgstr "Vanha nimi" #~ msgid "New Name" #~ msgstr "Uusi nimi" #, fuzzy #~ msgid " Type:" #~ msgstr "Tyyppi" #, fuzzy #~ msgid "Size:" #~ msgstr "Koko" #, fuzzy #~ msgid "Family:" #~ msgstr "&Perhe:" #~ msgid "About" #~ msgstr "Tietoja" #~ msgid "&Style:" #~ msgstr "&Tyyli:" #~ msgid "Si&ze:" #~ msgstr "Ko&ko:" #~ msgid "UNICODE" #~ msgstr "UNICODE" gogglesmm-0.12.7/po/cs.mo0000644000175000001440000011507012063217121013664 0ustar sxjusersL| H+I+(f++++++-+0$,1U,5,, ,!,)---?-G-N-T-f-v-1-5---.'.V.u..za/ /7/ 0)01090 @0J03Q00"00!000!01"1 B1 M1 Y1e1k1 s111111 1 11K192J2Q2W2[2'_22 22"222 222223* 373 O3[3a3g3 ~33 3333333W3F4 b4n4 t4 4B444 45 5 5(5/5>5*G6-r6-66C67 "7-7 @7N7h77 777 7777777 778 )838<<8y888888 889%9499'n9 9+9999 9:":):/:1>: p:}:: : : ::: :: ::;" ; ,;8; T;b;y; ;"; ;; ; ; ;;;; < <"2<U<C\<<< << <<< =2=3B='v=2= = === >)> ;> G>4U>>%>>>>%>?"?1? :?G?L@]@ c@p@WA]A cApAAAA AA=A A B,B8GBB B"BBBBB B CC C'C-C 2C+j#k")kLk]ktkkk kk(l&l1m 3mD=m mmmmm)mn n-n5n =nGnZn^n cnpn ynnnn nn=n%o9o-Mo({oooo:oo p=!p4_ppp pppq !q ,q :qDq9Tqqqqq qqq rrr r +r6r2;rnrvrrr r r+r ss s *s 7sCsIses|ss0s sGs *t 4t@tPtftxttt0t4t)'u1Qu u uuuu0uvv(!vJv(\vvvv,vv,v w #w 0wG a o {ɊVҊP)z<85M@&ڌ<N]h6ƍGEE:׎ &' 0<M!\ ~@&ʏ!*BJ(S8|%ېE '5 LX>` .1Òndak͓ԓۓ "+.Crgk}4ĕ'$ #0#T2x4!&"D$g$̗=)EUk ֘" 0 ISirz ™"%-4 ,"6$sN{/qCAs_~]?M[DHjydJgLZ\B>h@,ee C3-^/H uLOfU#'{  +9?WowG=tcpN:YSy_4z abip7i@ E#k|K%cWRQ}( 6Utjv5d3[<8+1'~laGTI"OEh.uX&*0&F4znb! `9nVf DYM)RTxB`)=r5k\J. A0rl>Z$(qPgo<!F7;8:P2 ;1-X*%|mxIV}^2mSv]KwQ Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show Browser Show Browser Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s %s (%d)%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&Find&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Properties&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Sign up…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Tag&Track&View&Window&Yes?c - display a if c is not empty else display b. ?c - display c if not empty A DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAn incompatible (future) version of the database was found. This usually happens when you try to downgrade to a older version of GMM Press OK to continue and reset the database (all information will be lost!). Press Cancel to quit now and leave the database as is.Are you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBoldBookmarksBorder Border ColorBothBottomBrowseBy %sC&reateCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.Close button minimizes to trayColorsColumnsCondensedConditions may be used as well:Configure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default FontDefault value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDemiboldDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Extra BoldExtra CondensedExtra ExpandedExtra LightFailed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:Font & IconsFor some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHeavyHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport PlaylistImport Playlist… Import existing playlistImport new tracks Imports files not yet in the database.Importing Files...Import…Information… Library StatisticsInternet RadioInvalid TemplateItalicKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLightLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMediumMedium imagesMenu Menu Base ColorMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesObliqueOffOops. Database ErrorOpen Folder Location Open Folder Location.Options:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playbackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlay File or StreamPlay File or Stream… Play File or StreamPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please specify a file or url to play:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseReverse ItalicReverse ObliqueRowsS&earch for:SamplerateSaturation:ScrobbleSecurity WarningSelect FileSelect Normal FontSelect allSelected Selected Text ColorSemi CondensedSemi ExpandedService:Session Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Mini Player Ctrl-M Toggle Mini Player.Show Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playbackStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTags Press to change sorting order Press to change sorting orderTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.ThinThis version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTitle Format:Tooltip Tooltip ColorTopTotal Time:TrackTracks:Tray Tray Background ColorTurn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUltra CondensedUltra ExpandedUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.…Project-Id-Version: gogglesmm 0.10.0 Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2011-02-10 19:05+0100 Last-Translator: David Vachulka Language-Team: Czech Language: cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; Nastavit hlasitost Nastaví hlasitost Záložky Navštíví zazáložkované adresáře. Podle jména Zavřít filtr Zavře filtr Vytvořit nový adresář Vytvoří nový adresář. Azurová, fialová, žlutá Jít do domovského adresáře Zpátky do domovského adresáře. Jít do pracovního adresáře Zpátky do pracovního adresáře. Jít o adresář výše Přesune do adresáře výše. Skrýt skryté soubory Skryje skryté soubory a adresáře. Odstín, sytost, hodnota Vybrat barvu Přehrát následující skladbu Přehraje následující skladbu. Přehrát předchozí skladbu Přehraje předchozí skladbu. Červená, zelená, modrá Odstranit Resetovat Uložit Oddělení interpreti Sdílení interpreti Zobrazit prohlížeč Zobrazí prohlížeč Zobrazit detaily Zobrazí detailní seznam adresářů. Zobrazit skryté soubory Zobrazí skryté soubory a adresáře. Zobrazit ikony Zobrazí adresář s velkými ikonami. Zobrazit seznam Zobrazí adresář s malými ikonami. Spustit přehrávání Spustí přehrávání Zastavit přehrávání Zastaví přehrávání%T - titul %A - jméno alba %P - jméno interpreta alba %p - jméno interpreta skladby %N - číslo skladby (2 místa) %n - číslo skladby %G - žánr%T - název %A - jméno alba %P - jméno interpreta alba %p - jméno interpreta skladby %N - číslo skladby %G - žánr%s %s (%d)%s Kontaktujte podporu, jestliže chyba přetrvává.&O programu...&Přijmout&Alfa:&Audio&Zpětně&Modrá:&Prohlížeč Ctrl-B Zobrazí prohlížeč žánrů interpretů a alb.Z&rušit&Vyčistit záložky Vyčistí záložky.&Zavřít&Sloupce Změní viditelné sloupce.&Konfigurovat sloupce…&Ovládání&Kopírovat Ctrl-C Kopíruje vybrané skladby&Vytvořit&Vyjmout Ctrl-X Vyjme vybrané skladby&Adresář&Adresář&Neukládat&Editovat&Export&Jméno souboru:&Soubor(y)&Najít&Obecné&Zelená:&Nápověda&Domovská stránka&Ignorovat velikost&Import&Připojit GMM na last.fm... Připojí skupinu Goggles Music Manager na last.fm...&Přeskočit na aktuální skladbu Ctrl-J Zobrazí aktuálně přehrávanou skladbu.&Hudba&Následující&Ne&OKV&ložit Ctrl-V Vloží výběr ze schránky&Přehrát&Vlastnosti&Ukončit&Ukončit Ctrl-Q Ukončí aplikaci.Če&rvená:&OdstranitOdstranit &vše&Přejmenovat&Nahradit&Reportovat problém...&Uložit&Hledat&Nastavit záložky Zazáložkuje aktuální adresář.&Přihlásit se do last.fm…&Přihlásit se …&Přeskočit&Seřadit&Seřazení Změní seřazení.&Spustit časovač&Zastavit&Zastavit import&Synchronizovat&Tag&Skladba&Pohled&Okno&Ano?c - zobrazí a, jestliže není c prázdné, jinak zobrazí b. ?c - zobrazí c, jestliže není prázdné Nastala chyba DBus. Všechny funkce vyžadující sessionbus jsou zakázané.V&zhledAlbumInterpret albaObaly albAlba Stisknout pro změnu řazení Stisknutí změní řazeníAlba:Vše Vždy číst všechny značkyVšechna %d albaVšichni %d interpretiVšechny %d žánryVšechny žánryAlfa:Již existujeNekompatibilní (budoucí) verze databáze. Obvykle nastane při snížení na starší verzi GMM Stiskněte OK pro pokračování a vynulování databáze (všechny informace budou ztraceny!). Stiskněte Zrušit pro ukončení a ponechání databáze jak je.Jste si jistý smazáním nastavení %s?Jste si jistý smazáním souboru: %sJste si jistý, že chcete smazat seznam skladeb?InterpretInterpreti Stisknout pro změnu řazení Stisknutí změní řazeníInterpreti:AtributyChyba audio zařízeníAudio ovladač:Audio výstup nedostupný.Automatické číslování skladeb. Krok:Základní Základní barvaVelké ikonyBitrateTučnéZáložkyOkraj Barva okrajeObaDoleProhlížečPodle %sVy&tvořitNemohu vytvořitNemohu vytvořit adresář %s. Změnit jméno seznamu skladebZměnit...KanályVyberte pořadí informací pro zobrazení v seznamu skladeb.Vyčistit knihovnu?Vyčistit záložkyZavřít audio zařízení při pozastavení.Tlačítko zavřít minimalizuje do trayBarvySloupceÚzkéPodmínky můžou být použity následujícím způsobem:Konfigurace sloupcůPřipojení odmítnuto.Kopírovat Ctrl-C Kopíruje asociované skladby do schránky.Kopírovat Ctrl-C Kopíruje skladbu(y) to schránky.Kopírovat souborKopírovat soubor z: %s do: Kopírovat...Vytvořit nový adresářVytvořit seznam skladebVytvořit nový adresář:AktuálníUživatelskýAzurová:Chyba databázeChyba databáze: Nemohu získat všechna jména souborů.Výchozí fontVýchozí hodnota:Smazat seznam skladeb?Smazat nastaveníSmazat...Mazání souboruMazání souborůPolotučnéPopisDetailyAdresář:BlokovanýDiskZobrazit přehrávanou skladbu v titulkovém pruhuVý&razUpravit internetovou staniciUpravit seznam skladebUpravit informaci o skladběUpravit...Upravit... Upravit... F2 Upraví informace o skladbě.Kódování:EngineEkvalizérEkvalizér Ekvalizér:ChybaChyba kopírování souboruChyba mazání souboruChyba odkazu souborChyba přesunu souboruChyba při načtení knihovny/zásuvného moduluPře&sněFiltr pro vynechání Vynechá adresáře a/nebo soubory podle šablonyVynechat:RoztaženéExportovat albaExportovat interpretyExportovat žánrExportovat hlavní knihovnuExportovat seznam skladebExportovat skladbyExportovat skladby z alba do daného adresáře.Exportovat skladby interpreta do daného adresáře.Exportovat skladby do daného adresáře.Exportovat skladby žánru do daného adresáře.Export…Extra tučnéExtra zhuštěnéExtra roztaženéExtra nepatrnéNemohu otevřít požadovaný audio ovladač: %sFatální chybaF&iltr souborů:Soubor už existuje. Chcete ho přepsat?Soubor nenalezen.Soubor nebo adresář %s již existuje. Soubor:Jméno souboruŠablona jména souboruJména souborů nevyžadují žádnou změnuSoubory:Najít Ctrl-F Zobrazí filtr vyhledávání.Adresáře:Font & IkonyZ nějakého důvodu je FOX knihovna byla zkompilována bez podpory PNG. Pro zobrazení ikon, Goggles Music Manager potřebuje podporu PNG ve FOX knihovně. Při vlastní kompilaci FOX, toto nastane, když nejsou nainstalovány hlavičkové soubory libpng v systému.Přehrávání bez mezerŽánrObří obrázkyGoggles Music Manager nemohl otevřít databázi. Databáze může být poškozená. Odstraňte ~/.goggles/goggles.db a zkuste znovu. Jestliže chyba přetrvává, reportujte na http://code.google.com/p/gogglesmmSkupinaHustéSkryté souboryZvýrazněné Barva zvýrazněníDomovský adresářOdstín:IkonyIgnorovat velikostIgnorovat první slovaImportovat složku... Ctrl-O Importuje hudbu ze složky do knihovnyImportovat hudbuNačíst seznam skladebNačíst seznam skladeb... Načte existující seznam skladebImportovat nové skladby Importuje soubory, které nejsou v databázi.Import souborů...Import…Informace... Statistiky o knihovněInternetové rádioNeplatná šablonaKurzívaPonechat seznamy skladebVelké ikonyChyba Last.FMLast.fmChyba knihovnyNepatrnéOdkazOdkázat souborLinkovat soubor z: %s do: Odkazovat...AdresaUmístění:Malá písmenaMalá písmena příponyFialová:RučníStředníStřední obrázkyMenu Základní barva menuMenu Barva menuDatum úpravyUpravené od posledního importu Jenom znovu načte značky, jestliže byl soubor změněn.Posunout dolůPřesunutí souboruPosunout nahoruPřesunout soubor z: %s do: Přesunout...Hudební knihovnaInformace o knihovněJménoSíť není dostupná.Nová internetová staniceNový seznam skladeb... Vytvoří nový seznam skladeb.Nový seznam skladebNový seznam skladeb... Vytvoří nový seznam skladebNová rádiová stanice... Vytvoří novou staniciNová stanice… Nové skladby:Nový adresář...NásledujícíNásledující Přehrát následující skladbu Přehraje následující skladbu.Následující skladbaNásledující skladba Ctrl-] Přehraje následující skladbu.Beze změnSkladby nebyly aktualizovány. Chcete stále zapsat značky pro vybrané skladby?Č.NormálníNormální Barva normálního textuNormální obrázkyŠikméVypnoutAjaj. Chyba databázeOtevřít adresář Otevře adresář.Volby:Přepsat souborPřepsat nastaveníPře&dchozíNastavení analýzyAnalyzovat z:Heslo:PozastavitPozastavit Pozastavit Pozastaví přehráváníPozastaví přehráváníPozastaví přehrávání.PřehrátPřehrát Ctrl-P Spustí přehrávání.Přehrát Spustit přehrávání Spustí přehráváníPřehrát soubor nebo přenosPřehrát soubor nebo přenos... Přehraje soubor nebo přenosPřehráváníChyba přehráváníOvládání přehrávačePřehrávané Barva přehrávané skladbyVložte jméno nastavení:Zadejte soubor nebo url k přehrání:Prosím vyčkejte. Může to zabrat nějaký čas.Pre-ampVolbyNastavení...Nastavení %s už existuje. Chcete ho přepsat?Jméno nastaveníPřednastaveno:Náhledové obrázkyPředchozíPředchozí Přehrát předchozí skladbu Přehraje předchozí skladbu.Předchozí skladbaPředchozí skladba Ctrl-[ Přehraje předchozí skladbu.FrontaUkončitNa&hradit všeChyba čteníJen pro čteníPřipraven.Odstranit Odstraní.Odstranit album?Odstranit všechny skladby Odstraní všechny skladby z knihovnyOdstranit interpreta?Odstranit audio soubory...Odstranit audio soubory?Odstranit žánr?Odstranit internetovou rádiovou stanici(e) z knihovny?Odstranit internetovou rádiovou stanici(e)?Odstranit seznam skladebOdstranit skladbu(y)?Odstranit všechny skladby z knihovny?Odstranit skladbu(y) z knihovny?Odstranit skladbu(y) ze seznamu skladeb?Odstranit skladby nalezené ve složce z databázeOdstranit skladby z alba z knihovny?Odstranit skladby z alba ze seznamu skladeb?Odstranit skladby interpreta z knihovny?Odstranit skladby interpreta ze seznamu skladeb?Odstranit skladby z diskuOdstranit skladby z knihovnyOdstranit skladby, které byly smazány z diskuOdstranit skladby žánru z knihovny?Odstranit skladby žánru ze seznamu skladeb?Odstranit... Del Odstraní žánr z knihovny.Odstranit... Del Odstraní asociované skladby z knihovny.Odstranit... Del Odstraní skladbu(y) z knihovny.Odstranit... Del Odstraní skladbu(y) ze seznamu skladeb.Přejmenovat audio soubory?Přejmenování audio souborů...Opakovat AOpakovat A-BOpakovat A-B Ctrl-T Opakuje část skladeb.Opakovat všechny skladby Ctrl-/ Opakuje všechny skladby.Opakovat Ctrl-, Opakuje aktuální sladbu.Opakovat skladbu Ctrl-. Opakuje aktuální skladbu.Nahradit &s:Nahradit mezery podtrženímNahradit podtržení mezeramiZisk přehrávání:Zdroje nejsou dostupné. Zkontrolujte právaObráceněObrácená kurzívaObráceně šikméŘádkyH&ledat:SamplerateSytost:ScrobbleBezpečnostní varováníVybrat souborVybrat fontVybrat všeVybraná Barva vybraného textuPolo zhuštěnéPolo roztaženéSlužba:Session bus není dostupný. Všechny funkce vyžadující sessionbus jsou zakázané.Session bus není dostupný. Všechny funkce vyžadující dbus jsou zakázané.Nastavit záložkyNastavit šablonu pro export...Nastavit číslo skladby založené na pořadí skenování.Nastavit čas uspáníStín Barva stínuZobrazit žán&ry Ctrl-G Zobrazí prohlížeč žánrů.Zobrazit &zdroje Ctrl-S Zobrazí prohlížeč zdrojůZobrazit prohlížečZobrazit přes celou obrazovku F12 Přepne mód celé obrazovky.Zobrazit ikony v prohlížeči skladebZobrazit popisyZobrazit mini přehrávač Ctrl-M Přepne mini přehrávač.Zobrazit stavový řádekZobrazit upozornění na změnu skladby Informuje upozorňovacího démona na změnu skaldby.Zobrazit tray ikonu Zobrazí tray ikonu v system tray.Zobrazit obal přehrávané skladby Zobrazí obal přehrávané skladbyZobrazit obaly v prohlížeči alb Zobrazí obaly v prohlížeči albNáhodně Ctrl-RNáhodně Alt-R Přehrává skladby v náhodném pořadí.VelikostPřeskočit &všeČas uspáníČas uspání Nastaví čas uspání.Uspat zaMalé ikonyVolby seřazeníSeřadit podleSeřadit podle roku vydání albaSeřazeníZdroje Stisknout pro změnu řazení Stisknutí změní řazeníZadejte jméno nového seznamu skladebZadejte url a popis nové staniceSpustí přehráváníSpustí přehrávání.StaniceZastavitZastavit Ctrl-\ Zastaví přehrávání.Zastavit Zastavit přehrávání Zastaví přehráváníZastavit přehrávání za daný časStyl:Synchronizovat složku... Synchronizuje složku s hudbou v knihovněSynchronizaceSynchronizovat složkuSystem TrayZnačkaTagy Stisknout pro změnu řazení Stisknutí změní řazeníŠablona může obsahovat absolutní nebo relativní cestu, proměnné prostředí a ~. Relativní cesty jsou založeny na umístění souboru. Přípony souboru budou automaticky přidány. Následující makra můžou být použity:Šablona:Následující audio soubory budou odstraněnyNásledující audio soubory budou přejmenoványDaná šablona není platná. Jméno skladby %%T musí být definováno. Upravte šablonu v panelu nastavení.TenkéTato verze Goggles Music Manager nepodporuje Last-FM. Prosím upgradujte na novější verzi GMM.DélkaNázevFormát názvu:Tooltip Barva tooltipNahořeCelková délka:SkladbaSkladby:Tray Barva pozadí trayVypnout engine přehrávání při zastavení.Zapnout engine přehrávání při startu. Pro rychlejší spuštění, engine přehrávání se normálně při přehrávání první skaldby. Pro rychlejší spuštění, engine přehrávání se normálně při přehrávání první skaldby.TypUltra zhuštěnéUltra roztaženéNemohu kopírovat soubor: %s do: %s Pokračovat?Nemohu vytvořit adresář %s Nemohu smazat soubor: %s Pokračovat?Nemohu inicializovat audio ovladač.Nemohu vložit skladbu do databázeNemohu spustit webový prohlížečNemohu linkovat soubor: %s do: %s Pokračovat?Nemohu přesunout soubor: %s do: %s Pokračovat?Nemohu otevřít databáziNemohu odstranit album z knihovnyNemohu odstranit interpreta z knihovnyNemohu odstranit žánr z knihovnyNemohu odstranit stanici z knihovny.Nemohu odstranit skladbu z knihovny.Nemohu přejmenovat souborNemohu přejmenovat: %s na:%sNemohu přejmenovat: %s na:%s Pokračovat v přejmenování?Nemohu aktualizovat skladbuNeznámá chybaNeznámé zařízeníNeznámý hostitel.Bez názvuO úroveň výšAktualizovat jméno souboruAktualizovat značku v souboruAktualizovat značky?Aktualizovat existující skladby:Aktualizace url a popisu staniceAktualizace databáze...UživatelUživatelské jméno:Hodnota:NáhledNormalizace hlasitostiVarováníOknoPracovní adresářRokŽlutá:Kolekce hudby se skládá z...alt bg Alternativní barva pozadíbg Barva pozadí fg Barva textuhodin aminut.…gogglesmm-0.12.7/po/ru.mo0000644000175000001440000013163012063217122013706 0ustar sxjusersi &&(&&+','-C'0q'1'5' ( "(!.()P(z((((((1(5(-+).Y))))z*7+ F+P+X+`+ g+q+3x++"++!+,,!,A,I, i, t, ,,, ,,,,, , ,,K,91-k-r-x-|-'---"--- ---...*!.L.d.j.p. .. ......F./ / !/B./q/y/ // / ///*/- 0-70e0Cl00 00 0001 *141 <1F1Z1_1f1m1 s111 11<122(2E2L2 T2^2p242'2 2+23343 D3e3m3t3z31333 3 3 34 44 %40494">4 a4m4 444 4"4 44 4 4 555.5B5U5"g55C555 55 66%6 662D63w6'626 7)7 :7 F74T77%7777%78" 80898>9O9 U9b9I: O:\:p::: ::=: :8:/;"B;e;t;; ; ;; ;; ;+;<< < <&<;<D< K<Y< n<O|< < <<+<= =*=D=I=`=){= =&=+=> >">3>%8> ^>&i> >W>>> ?!?6???O? `?j?y? ?????"??@@!@=@#W@{@ @@9@ @@@@1A7A&FAmAsA xA A AAA A5AABB .B.y y@z HzSz |0|'9|Ja| }}4}~$~ ,~'9~@a~~'"JB:V#tɀ!р ,9-gw5Ɓ%'Em?!_/+˃C;B5aKJSJ)ȅ߅ ZA+*# N"Z%}!%ۈ  OjNrԉG+`0K% \/ M/Nc^ h w ύݍ\&v'%ŎX>]Rُ6,4cUXVG`^'^J;ђT RbH]L\J1;&brGO˕PLl>і> OJ\" ʗ ח5.GvAxΘlG% ڙX6TQaZz<#84\o9_ q' !ßZ@^x@ 3TF`Pu|ƢZC +0+\ fBtN .  QnY2UHPѫG"=jcY 9fJTF@XG8(:az.#F+j"+˰"%@5[K*ݱ !-?#Fj I5 ?)T ~ +_lAz,*qgnvJwV.]=S}m3n X 7Lhyf6N<h`0#<2B:VaT> jDqEI>! 'ob&_ez R2G4?=\)w(aFp /;IX9~MCQjgKPvE6pUd4;W(AsO5{T,%5|W~OeM rRtUl#Cdi8P$\Gf%  8|c}] NH:J xtk1xyKZr/'!7"bu-@9^" u&+.1iFB`cmH{[s*YD^@-0Z)[L?oS3Q$kY Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Track&View&Window&YesA DBus error occurred. All features requiring sessionbus are disabled.AlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAre you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBookmarksBorder Border ColorBothBottomBrowseBy %sCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.ColorsColumnsCondensedConfigure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Failed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:For some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport new tracks Imports files not yet in the database.Importing Files...Information… Library StatisticsInternet RadioInvalid TemplateKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMedium imagesMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?NormalNormal Normal Text ColorNormal imagesOops. Database ErrorOptions:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseRowsS&earch for:SamplerateSaturation:Security WarningSelect Normal FontSelect allSelected Selected Text ColorSession Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.This version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTooltip Tooltip ColorTopTotal Time:TrackTracks:Turn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.Project-Id-Version: gogglesmm 0.10.0 Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2010-01-24 20:10+0300 Language-Team: Russian Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L Lawliet Выровнять громкость Выровнять громкость Закладки Перейти в запомненные папки По имени Создать новую папку Создать новую папку Голубой, пурпурный, желтый Перейти в домашнюю папку Вернуться в домашнюю папку. Перейти в рабочую папку Вернуться в рабочую папку. Перейти на уровень выше Перейти на уровень выше Скрыть скрытые файлы Скрыть скрытые файлы и папки. Тон, насыщенность, величина Выбрать цвет Проиграть следующий трек Проиграть следующий трек Проиграть предыдущий трек Проиграть предыдущий трек Красный, зеленый, синий Удалить Сбросить Сохранить Объединить исполнителей Разделить исполнителей Показать детальный список Отобразить детальный вид папки. Показать скрытые файлы Показать скрытые файлы и папки. Показать иконки Отобразить папку с крупными иконками. Показать список Отобразить папку с маленькими иконками. Начать воспроизведение Начать воспроизведение Остановить воспроизведение Остановить воспроизведение%T - название %A - название альбома %P - имя исполнителя альбома %p - имя исполнителя трека %y - год %d - номер диска %N - номер трека (2 цифры) %n - номер трека %G - жанр%T - название %A - название альбома %P - имя исполнителя альбома %p - имя исполнителя трека %N - номер трека %G - жанр%s Пожалуйста, обратитесь в поддержку, если эта ошибка продолжает появляться.&О программе&Принять&Прозрачность:&АудиоВ &обратном порядке&Синий:&Просмотреть Ctrl-B Показать браузер по жанрам, исполнителям и альбомам.&Отменить&Очистить закладки Очистить закладки.&Закрыть&Столбцы Изменить видимые столбцы.&Настроить столбцы...&Управление&Копировать Ctrl-C Копировать выделенные треки&Создать&Вырезать Ctrl-X Вырезать выделенные треки&Папка&Папка:&Не сохранятьР&едактировать&ЭкспортироватьИмя &файла&Файл(ы)&Общие&Зеленый:&Справка&Домашняя страница&Игнорировать регистр&ИмпортироватьПрисоединиться к GMM на last.fm... Присоединиться к группе Goggles Music Manager group на last.fm...&Перейти на проигрываемый трек Ctrl-J Показать проигрываемый трек.&Музыка&Следующий&Нет&OKВст&авить Ctrl-V Вставить из буфера обмена&ИгратьВ&ыходВы&ход Ctrl-Q Выход из приложения.&Красный:&Удалить&Удалить все&Переименовать&ЗаменитьСо&общить об ошибке...Со&хранить&НайтиСоздать закладку Сохранить данную директорию в закладках.&Зарегистрироваться на last.fm...&Пропустить&СортироватьСор&тировка Изменить сортировку.&Запустить таймер&СтопО&становить импорт&Синхронизировать&Трек&Вид&Окно&ДаПроизошла ошибка DBus. Все функции, требующие сессию bus, недоступны.АльбомИсполнитель альбомаОбложки альбомовАльбомы Нажмите, чтобы изменить порядок сортировки Нажмите, чтобы изменить порядок сортировкиАльбомов:Все Всегда читать тегиВсе %d альбомыВсе %d исполнителиВсе %d жанрыВсе жанрыПрозрачность:Уже существуетВы уверены, что хотите удалить %s пресет?Вы уверены, что хотите удалить файл: %sВы уверены, что хотите удалить плейлист?ИсполнительИсполнители Нажмите, чтобы изменить порядок сортировки Нажмите, чтобы изменить порядок сортировкиИсполнителей:АтрибутыОшибка аудио устройстваАудио драйверАудио выход недоступен.Автоматический номер трека. Смещение:Базовый Базовый цветКрупные значкиБитрейтЗакладкиРамка Цвет рамкиВездеВнизуПросмотретьПо %sНевозможно создатьНевозможно создать папку %s. Переименовать плейлистИзменить...КаналыВыбрать порядок отображения информации в трек-листеОчистить музыкальную библиотеку?Очистить закладкиЗакрывать аудио устройство при паузе.ЦветаСтолбцыУплотненнаяУпорядочить столбцыСоединение отклонено.Копировать Ctrl-C Копировать связанные треки в буфер обмена.Копировать Ctrl-C Копировать трек(и) в буфер обмена.Копировать файлаКопировать файл из: %s в: Копировать...Создать новую папкуСоздать плейлистСоздать новую папку с именем: ТекущийВыборочноГолубой:Ошибка базы данныхОшибка базы данных: Невозможно найти все имена файловПо умолчанию:Удалить плейлист?Удалить пресетУдалить...Удаление файловУдаление файловОписаниеДеталиПапка:НедоступныйДискОтображать проигрываемый файл в названии окнаВ&ыражениеРедактировать интернет радио-станциюРедактировать плейлистРедактировать информацию о трекеРедактировать...Редактировать... Редактировать... F2 Редактировать информацию о треке.Кодировка:ДвижокЭквалайзерЭквалайзер Эквалайзер:ОшибкаОшибка при копировании файлаОшибка удаления файловОшибка создания файловой ссылкиОшибка при перемещении файлаОшибка загрузки библиотеки/плагина&ТочноОтключить фильтр Отфильтровать папки и/или файлы по шаблонуИсключить:РазреженнаяЭкспортировать альбомыЭкспортировать исполнителейЭкспортировать жанрЭкспортировать главную библиотекуЭкспортировать плейлистЭкспортировать трекиЭкспортировать реки из альбома в выбранную папку.Экспортировать треки исполнителя в выбранную папку.Экспортировать треки в выбранную папку.Экспортировать треки выбранного жанра в выбранную папку.Экспортировать...Не удается открыть требуемый аудио драйвер: %sКритическая ошибкаФайловый ф&ильтрФайл уже существует. Перезаписать его?Файл не найден.Файл или папка %s уже существует. Файл:Имя файлаШаблоны имен файловИмена файлов не требуют измененийФайлыНайти... Ctrl-F Показать фильтр поиска.ПапкиПо каким-то причинам библиотека FOX была скомпилирована без поддержки PNG. Для отображения всех иконок Goggles Music Manager требует поддержку PNG в библиотеке FOX. Если Вы сами компилируете FOX, вероятно заголовочные файлы libpng не установлены в Вашей системе.Gapless проигрываниеЖанрОгромные изображенияGoggles Music Manager не может открыть базу данных. Вероятно база данных повреждена. Удалить файл ~/.goggles/goggles.db и попробуйте снова. Если ошибка не исчезнет, сообщите о ней на http://code.google.com/p/gogglesmmГруппаСкрытые файлыВыделенный Цвет выделенногоДомашняя папкаТон:ИконкиИгнорировать регистрИгнорировать предшествующие словаИмпортировать папку... Ctrl-O Импортировать музыку из папки в библиотекуИмпортировать музыкуИмпортировать новые треки Импортировать файлы, не содержащиеся в базе данных.Импорт файлов...Информация... Статистика библиотекиИнтернет радиоНеверный шаблонОставить плейлистыБольшие иконкиОшибка Last.FMLast.fmОшибка библиотекиСсылкаСоздать файловую ссылкуСоздать ссылку на файл из: %s в: Ссылка...РасположениеРасположение:Нижний регистрРасширение в нижнем регистреПурпурный:ВручнуюСредние изображенияМеню Цвет текста менюДата измененияИзмененные после последнего импорта Перечитать тег,только если файл был изменен.Переместить внизПереместить файлПереместить вверхПереместить файл из: %s в: Переместить...Музыкальная библиотекаИнформация о музыкальной библиотекеИмяСеть недоступна.Новая интернет радио-станцияНовый плейлист... Создать новый плейлист.Новый плейлистНовый плейлист... Создать новый плейлистНовая радио-станция... Создать новый плейлистНовая радио-станция... Новые треки:Новая папка...СледующийСледующий Воспроизвести следующий трек Воспроизвести следующий трек.Следующий трекСледующий трек Ctrl-] Воспроизвести следующий трек.Изменений нетТреки не были обновлены. Хотите ли Вы записать теги в выделенные треки?НормальнаяНормальный Цвет нормального текстаНормальные изображенияУпс. Ошибка базы данныхОпции:Перезаписать файл?Перезаписать пресетП&редыдущийНастройки разбораИскать информацию в:Пароль:ПаузаПауза Пауза Приостановить воспроизведениеВоспроизвестиВоспроизвести Ctrl-P Начать воспроизведение.Воспроизвести Начать воспроизведение Начать воспроизведениеПроигрываниеОшибка воспроизведенияКнопки управления плееромПроигрываемый Цвет проигрываемого трекаВведите имя пресета:Пожалуйста, подождите. Это займет некоторое время.Pre-ampОпцииОпцииПресет %s уже существует. Перезаписать его?Имя пресетаПресеты:Предпросмотр изображенийПредыдущийПредыдущий Воспроизвести предыдущий трек Воспроизвести предыдущий трек.Предыдущий трекПредыдущий трек Ctrl-[ Воспроизвести предыдущий трек.ОчередьВыйтиЗа&менить всеОшибка чтенияТолько чтениеГотово.Удалить УдалитьУдалить альбом?Удалить все треки Удалить все треки из библиотекиУдалить исполнителя?Удалить аудио-файлы...Удалить аудио-файлы?Удалить жанр?Удалить интернет радио-станцию(и) из библиотеки?Удалить интернет радио-станцию(и)?Удалить плейлистУдалить трек(и)?Удалить все файлы из музыкальной библиотеки?Удалить трек(и) из библиотеки?Удалить трек(и) из плейлиста?Удалить найденные в папке треки из базы данныхУдалить треки выбранного альбома из библиотеки?Удалить треки выбранного альбома из плейлиста?Удалить треки выбранного исполнителя из библиотеки?Удалить треки выбранного исполнителя из плейлиста?Удалить треки с дискаУдалить треки из музыкальной библиотекиУдалить треки, удаленные с дискаУдалить треки выбранного жанра из библиотеки?Удалить треки выбранного жанра из плейлиста?Удалить... Del Удалить жанр из библиотеки.Удалить... Del Удалить связанные треки из библиотеки.Удалить... Del Удалить трек(и) из библиотеки.Удалить... Del Удалить трек(и) из плейлиста.Переименовать аудио-файлы?Переименовывание аудио-файлов...Повтор АПовтор A-BПовторять A-B Ctrl-T Повторять часть трека.Повторять все треки Ctrl-/ Повтор всех треков.Выключить повтор Ctrl-, Повтор текущего трека.Повторять трек Ctrl-. Повтор текущего трека.Заменить &на:Заменить пробелы подчеркиваниямиЗаменить подчеркивания пробеламиReplay Gain:Ресурс недоступен. Проверьте разрешенияВ обратном порядкеСтроки&Найти:СемплрейтНасыщенность:Предупреждение безопасностиВыбрать нормальный шрифтВыбрать всеВыделенный Цвет выделенного текстаСессия bus недоступна. Все функции, требующие сессию bus, недоступны.Сессия bus недоступна. Все функции, требующие dbus, недоступны.Установить закладкуШаблон экспорта...Установить номер трека по порядку сканирования.Установить таймер выключенияТень Цвет тениПоказать &жанры Ctrl-G Показать браузер жанров.Показать &источники Ctrl-S Показать браузер источников Показать браузерПоказать в полноэкранном режиме F12 Переключить в полноэкранный режим.Прятать иконке в браузере трековПоказывать подписиПоказывать строку состоянияПоказывать сообщение при смене трека Показывать информационное сообщение при смене трека.Отображать иконку в трее Отображать иконку в системном трее.Показывать обложку альбома проигрываемого трека Показывать обложку альбома проигрываемого трекаПоказывать обложку альбома в браузере обложек Показывать обложку альбома в браузере обложекПеремешать Ctrl-RСлучайный режим Alt-R Воспроизводить треки в случайном порядке.РазмерПропустить &всеТаймер выключенияТаймер выключения Установить таймер выключения.Выключить черезМелкие значкиОпции сортировкиСортировать поСортировать по году выхода альбомаСортировкаИсточники Нажмите, чтобы изменить порядок сортировки Нажмите, чтобы изменить порядок сортировкиЗадать имя нового плейлистаУкажите ссылку и описание новой радио-станцииРадио-станцияОстановитьОстановить Ctrl-\ Остановить воспроизведение.Остановить Остановить воспроизведение Остановить воспроизведениеОстановить воспроизведение через заданное времяСтиль:Синхронизировать папку... Синхронизировать папку с музыкой и библиотекуОперация синхронизацииСинхронизировать папкуСистемный трейТегШаблон может содержать абсолютный или относительный путь, переменные окружения и ~. Относительный путь базируется на расположении оригинального файла. Расширение файла добавляется автоматически. Могут быть использованы следующие макросы:Шаблон:Следующие аудио-файлы будут удаленыСледующие аудио-файлы будут переименованыВведенный шаблон неверен. Название трека %%T должно быть определеноПожалуйста исправьте шаблон имени файла в панели настроек.Эта версия Goggles Music Manager не поддерживает Last-FM. Пожалуйста, обновитесь до более новой версии GMM.ВремяНазваниеПодсказка Цвет подсказкиВверхуОбщее время:ТрекТреков:Выключать движок проигрыванию при останове.Включение движка проигрывания при старте. Для быстрого старта, движок проигрывания запускается при первом проигрывании трека. Для быстрого старта, движок проигрывания запускается при первом проигрывании трека.ТипНевозможно скопировать файл: %s to: %s Продолжить?Невозможно создать папку %s Невозможно удалить файл: %s Продолжить?Невозможно инициализировать аудио драйвер.Невозможно добавить трек в базу данныхНевозможно запустить веб-браузерНевозможно создать ссылку на файл: %s в: %s Продолжить?Невозможно переместить файл: %s to: %s Продолжить?Невозможно открыть базу данныхНевозможно удалить альбом из библиотекиНевозможно удалить исполнителя из библиотекиНевозможно удалить жанр из библиотекиНевозможно удалить радио-станцию из библиотеки.Невозможно удалить трек из библиотеки.Невозможно переименовать файлНевозможно переименовать: %s в:%sНевозможно переименовать: %s в:%s Продолжить переименование файлов?Невозможно обновить трекНеизвестная ошибкаНеизвестное устройствоНеизвестный адрес.Без имениПерейти на уровень вышеОбновить имя файлаОбновить тег в файлеОбновить теги?Обновить существующие треки:Обновить ссылку и описание радио-станцииОбновление базы данныхПользовательЛогин:Величина:ВидНормализация звукаПредупреждениеОкноРабочая папкаГодЖелтый:Ваша музыкальная коллекция состоит из...alt bg Альтернативный цвет фонаbg Цвет фонаfg Цвет переднего планачасов иминут.gogglesmm-0.12.7/po/ru.po0000644000175000001440000024724611524673460013740 0ustar sxjusers# Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the PACKAGE package. # L Lawliet , 2010. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.0\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2010-01-24 20:10+0300\n" "Language-Team: Russian\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "L Lawliet \n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Закрыть" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Упорядочить столбцы" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Принять" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Отменить" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Выбрать порядок отображения информации\n" "в трек-листе" #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Переместить вверх" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Переместить вниз" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Неверный шаблон" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" "Введенный шаблон неверен. Название трека %%T должно быть " "определеноПожалуйста исправьте шаблон имени файла в панели настроек." #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Ошибка базы данных" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Упс. Ошибка базы данных" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Изменений нет" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Имена файлов не требуют изменений" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Переименовать аудио-файлы?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Переименовывание аудио-файлов..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "Следующие аудио-файлы будут переименованы" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "&Переименовать" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Невозможно переименовать файл" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "Невозможно переименовать:\n" "%s\n" "\n" "в:%s\n" "Продолжить переименование файлов?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "Невозможно переименовать:\n" "%s\n" "\n" "в:%s" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Шаблоны имен файлов" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "Шаблон может содержать абсолютный или относительный путь, переменные\n" "окружения и ~. Относительный путь базируется на расположении оригинального\n" "файла. Расширение файла добавляется автоматически. Могут быть использованы\n" "следующие макросы:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - название %A - название альбома\n" "%P - имя исполнителя альбома %p - имя исполнителя трека\n" "%y - год %d - номер диска\n" "%N - номер трека (2 цифры) %n - номер трека \n" "%G - жанр" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Шаблон:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Кодировка:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Исключить:" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Опции:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Заменить пробелы подчеркиваниями" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Нижний регистр" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Расширение в нижнем регистре" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 #, fuzzy msgid "No." msgstr "Нет" #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Очередь" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Название" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Исполнитель" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Исполнитель альбома" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Альбом" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Диск" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Жанр" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Год" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Время" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Удалить...\tDel\tУдалить жанр из библиотеки." #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Копировать\tCtrl-C\tКопировать связанные треки в буфер обмена." #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Удалить...\tDel\tУдалить связанные треки из библиотеки." #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Редактировать...\tF2\tРедактировать информацию о треке." #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Копировать\tCtrl-C\tКопировать трек(и) в буфер обмена." #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Удалить...\tDel\tУдалить трек(и) из библиотеки." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Новый плейлист...\t\tСоздать новый плейлист." #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Экспортировать..." #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Информация...\t\tСтатистика библиотеки" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "Удалить все треки\t\tУдалить все треки из библиотеки" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Редактировать информацию о треке" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "Со&хранить" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Свойства" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Имя файла" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Тип" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Размер" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Битрейт" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Семплрейт" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Каналы" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Трек" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tОбъединить исполнителей" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tРазделить исполнителей" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Автоматический номер трека. Смещение:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Обновить тег в файле" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Обновить имя файла" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Шаблон экспорта..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Обновить теги?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Треки не были обновлены.\n" "Хотите ли Вы записать теги в выделенные треки?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Удалить аудио-файлы?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Удалить аудио-файлы..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Следующие аудио-файлы будут удалены" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Удалить" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Экспортировать главную библиотеку" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Экспортировать плейлист" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Перезаписать файл?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "Файл уже существует. Перезаписать его?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Экспортировать жанр" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Экспортировать треки выбранного жанра в выбранную папку." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Экспортировать исполнителей" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Экспортировать треки исполнителя в выбранную папку." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Экспортировать альбомы" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Экспортировать реки из альбома в выбранную папку." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Экспортировать треки" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Экспортировать треки в выбранную папку." #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Экспортировать" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Удалить жанр?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Удалить треки выбранного жанра из библиотеки?" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Удалить исполнителя?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Удалить треки выбранного исполнителя из библиотеки?" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Удалить альбом?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Удалить треки выбранного альбома из библиотеки?" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Удалить трек(и)?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Удалить трек(и) из библиотеки?" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Удалить треки с диска" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Ошибка библиотеки" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "Невозможно удалить жанр из библиотеки" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Невозможно удалить исполнителя из библиотеки" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Невозможно удалить альбом из библиотеки" #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "Невозможно удалить трек из библиотеки." #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Создать плейлист" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Задать имя нового плейлиста" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Создать" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Имя" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Новый плейлист" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Очистить музыкальную библиотеку?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Удалить все файлы из музыкальной библиотеки?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Удалить все" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Оставить плейлисты" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Информация о музыкальной библиотеке" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Ваша музыкальная коллекция состоит из..." #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Треков:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Исполнителей:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Альбомов:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Общее время:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Эквалайзер" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Эквалайзер:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tСохранить" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tСбросить" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tУдалить" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Pre-amp" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Недоступный" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Вручную" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Удалить пресет" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Вы уверены, что хотите удалить %s пресет?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Имя пресета" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Введите имя пресета:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Перезаписать пресет" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "Пресет %s уже существует. Перезаписать его?" #: src/GMFontDialog.cpp:209 #, fuzzy msgid "Ultra Condensed" msgstr "Ультра-уплотненная" #: src/GMFontDialog.cpp:210 #, fuzzy msgid "Extra Condensed" msgstr "Экстра-уплотненная" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Уплотненная" #: src/GMFontDialog.cpp:212 #, fuzzy msgid "Semi Condensed" msgstr "Полу-уплотненная" #: src/GMFontDialog.cpp:214 #, fuzzy msgid "Semi Expanded" msgstr "Полу-разреженная" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Разреженная" #: src/GMFontDialog.cpp:216 #, fuzzy msgid "Extra Expanded" msgstr "Экстра-разреженная" #: src/GMFontDialog.cpp:217 #, fuzzy msgid "Ultra Expanded" msgstr "Ультра-разреженная" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 #, fuzzy msgid "Extra Light" msgstr "экстра легкий" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 #, fuzzy msgid "Light" msgstr "легкий" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 #, fuzzy msgid "Medium" msgstr "средний" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 #, fuzzy msgid "Demibold" msgstr "полужирный" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 #, fuzzy msgid "Extra Bold" msgstr "очень жирный" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 #, fuzzy msgid "Heavy" msgstr "тяжелый" #: src/GMFontDialog.cpp:239 #, fuzzy msgid "Reverse Oblique" msgstr "обратный наклонный" #: src/GMFontDialog.cpp:240 #, fuzzy msgid "Reverse Italic" msgstr "обратный курсив" #: src/GMFontDialog.cpp:242 #, fuzzy msgid "Italic" msgstr "курсив" #: src/GMFontDialog.cpp:243 #, fuzzy msgid "Oblique" msgstr "наклонный" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Нормальная" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "&Папка:" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "Имя &файла" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "Файловый ф&ильтр" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Только чтение" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Папка:" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "Создать закладку\t\tСохранить данную директорию в закладках." #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "&Очистить закладки\t\tОчистить закладки." #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tПерейти на уровень выше\tПерейти на уровень выше" #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tПерейти в домашнюю папку\tВернуться в домашнюю папку." #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tПерейти в рабочую папку\tВернуться в рабочую папку." #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tЗакладки\tПерейти в запомненные папки" #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tСоздать новую папку\tСоздать новую папку" #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tПоказать список\tОтобразить папку с маленькими иконками." #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tПоказать иконки\tОтобразить папку с крупными иконками." #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tПоказать детальный список\tОтобразить детальный вид папки." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "\tПоказать скрытые файлы\tПоказать скрытые файлы и папки." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "\tСкрыть скрытые файлы\tСкрыть скрытые файлы и папки." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Синхронизировать папку" #: src/GMImportDialog.cpp:414 #, fuzzy msgid "Import Playlist" msgstr "Экспортировать плейлист" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Импортировать музыку" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Файл(ы)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Папка" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "Отключить фильтр\tОтфильтровать папки и/или файлы по шаблону" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Папки" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Файлы" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Синхронизировать" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Операция синхронизации" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" "Импортировать новые треки\tИмпортировать файлы, не содержащиеся в базе " "данных." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Удалить треки, удаленные с диска" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Обновить существующие треки:" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" "Измененные после последнего импорта\tПеречитать тег,только если файл был " "изменен." #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Все\tВсегда читать теги" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Удалить найденные в папке треки из базы данных" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Трек" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Настройки разбора" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Искать информацию в:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Тег" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Везде" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "По умолчанию:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Установить номер трека по порядку сканирования." #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - название %A - название альбома\n" "%P - имя исполнителя альбома %p - имя исполнителя трека \n" "%N - номер трека %G - жанр" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Заменить подчеркивания пробелами" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Импортировать" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Невозможно инициализировать аудио драйвер." #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Неизвестный адрес." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Неизвестное устройство" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Сеть недоступна." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Аудио выход недоступен." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Соединение отклонено." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Файл не найден." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Ресурс недоступен. Проверьте разрешения" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Ошибка чтения" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Ошибка загрузки библиотеки/плагина" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Предупреждение" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Предупреждение безопасности" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Неизвестная ошибка" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Ошибка" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Невозможно создать папку %s\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "По каким-то причинам библиотека FOX была скомпилирована без поддержки PNG.\n" "Для отображения всех иконок Goggles Music Manager требует поддержку PNG в\n" "библиотеке FOX. Если Вы сами компилируете FOX, вероятно заголовочные файлы\n" "libpng не установлены в Вашей системе." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "Сессия bus недоступна. Все функции, требующие dbus, недоступны." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "Произошла ошибка DBus. Все функции, требующие сессию bus, недоступны." #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "Сессия bus недоступна. Все функции, требующие сессию bus, недоступны." #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Ошибка аудио устройства" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Ошибка Last.FM" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Ошибка воспроизведения" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Удалить...\tDel\tУдалить трек(и) из плейлиста." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Редактировать..." #: src/GMPlayListSource.cpp:162 #, fuzzy msgid "Import…" msgstr "Экспортировать..." #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Удалить плейлист" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Удалить треки выбранного жанра из плейлиста?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Удалить треки выбранного исполнителя из плейлиста?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Удалить треки выбранного альбома из плейлиста?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Удалить трек(и) из плейлиста?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Удалить треки из музыкальной библиотеки" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Редактировать плейлист" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Переименовать плейлист" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Удалить плейлист?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Вы уверены, что хотите удалить плейлист?" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Да" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Нет" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Опции" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Общие" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Опции сортировки" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Игнорировать предшествующие слова" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Обложки альбомов" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" "Показывать обложку альбома проигрываемого трека\tПоказывать обложку альбома " "проигрываемого трека" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" "Показывать обложку альбома в браузере обложек\tПоказывать обложку альбома в " "браузере обложек" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "Системный трей" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Отображать иконку в трее\tОтображать иконку в системном трее." #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" "Показывать сообщение при смене трека\tПоказывать информационное сообщение " "при смене трека." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "Эта версия Goggles Music Manager\n" "не поддерживает Last-FM. Пожалуйста,\n" "обновитесь до более новой версии GMM." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 #, fuzzy msgid "&Sign up…" msgstr "&Зарегистрироваться на last.fm..." #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Логин:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Пароль:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Окно" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Окно" #: src/GMPreferencesDialog.cpp:365 #, fuzzy msgid "Close button minimizes to tray" msgstr "Кнопка \"Закрыть\" прячет главное окно" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Показывать строку состояния" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Прятать иконке в браузере треков" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Отображать проигрываемый файл в названии окна" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Кнопки управления плеером" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Расположение:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Вверху" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Внизу" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Стиль:" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Показывать подписи" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Большие иконки" #: src/GMPreferencesDialog.cpp:399 #, fuzzy msgid "A&ppearance" msgstr "&Вид" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Цвета" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "fg\tЦвет переднего плана" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "bg\tЦвет фона" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt bg\tАльтернативный цвет фона" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Нормальный\tЦвет нормального текста" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Базовый\tБазовый цвет" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Выделенный\tЦвет выделенного текста" #: src/GMPreferencesDialog.cpp:433 #, fuzzy msgid "Menu\tMenu Base Color" msgstr "Меню\tЦвет текста меню" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Меню\tЦвет текста меню" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Рамка\tЦвет рамки" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Подсказка\tЦвет подсказки" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Выделенный\tЦвет выделенного" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Тень\tЦвет тени" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Проигрываемый\tЦвет проигрываемого трека" #: src/GMPreferencesDialog.cpp:463 #, fuzzy msgid "Tray\tTray Background Color" msgstr "bg\tЦвет фона" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Пресеты:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 #, fuzzy msgid "Default Font" msgstr "По умолчанию:" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Изменить..." #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Иконки" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Аудио" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Движок" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Аудио драйвер" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Закрывать аудио устройство при паузе." #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Выключать движок проигрыванию при останове." #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" "Включение движка проигрывания при старте.\tДля быстрого старта, движок " "проигрывания запускается при первом проигрывании трека.\tДля быстрого " "старта, движок проигрывания запускается при первом проигрывании трека." #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Проигрывание" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Replay Gain:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Gapless проигрывание" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Нормализация звука" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "Не удается открыть требуемый аудио драйвер: %s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Текущий" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Выборочно" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Невозможно запустить веб-браузер" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Выбрать нормальный шрифт" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Следующий" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "П&редыдущий" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Играть" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Стоп" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Показать браузер" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Выйти" #: src/GMRemote.cpp:385 #, fuzzy msgid "\tShow Browser\tShow Browser" msgstr "Показать браузер" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tНачать воспроизведение\tНачать воспроизведение" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tОстановить воспроизведение\tОстановить воспроизведение" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tПроиграть предыдущий трек\tПроиграть предыдущий трек" #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tПроиграть следующий трек\tПроиграть следующий трек" #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tВыровнять громкость\tВыровнять громкость" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Невозможно открыть базу данных" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "Ошибка базы данных: Невозможно найти все имена файлов" #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "Невозможно обновить трек" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Невозможно добавить трек в базу данных" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Критическая ошибка" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Пожалуйста, обратитесь в поддержку, если эта ошибка продолжает появляться." #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Обновление базы данных" #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Пожалуйста, подождите. Это займет некоторое время." #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Новые треки:" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "Файл:" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Импорт файлов..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "О&становить импорт" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" "Источники\tНажмите, чтобы изменить порядок сортировки\tНажмите, чтобы " "изменить порядок сортировки" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Новый плейлист...\t\tСоздать новый плейлист" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 #, fuzzy msgid "Import Playlist…\t\tImport existing playlist" msgstr "Новый плейлист...\t\tСоздать новый плейлист" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Новая радио-станция...\t\tСоздать новый плейлист" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Радио-станция" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Новая радио-станция...\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Редактировать...\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Удалить\t\tУдалить" #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Новая интернет радио-станция" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Укажите ссылку и описание новой радио-станции" #: src/GMStreamSource.cpp:168 #, fuzzy msgid "C&reate" msgstr "&Создать" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "Расположение" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "Описание" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Без имени" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Редактировать интернет радио-станцию" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Обновить ссылку и описание радио-станции" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Удалить интернет радио-станцию(и)?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Удалить интернет радио-станцию(и) из библиотеки?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Невозможно удалить радио-станцию из библиотеки." #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" "Goggles Music Manager не может открыть базу данных.\n" "Вероятно база данных повреждена. Удалить файл ~/.goggles/goggles.db и " "попробуйте снова.\n" "Если ошибка не исчезнет, сообщите о ней на http://code.google.com/p/gogglesmm" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "" #: src/GMTrackView.cpp:246 #, fuzzy msgid "&Find" msgstr "Найти" #: src/GMTrackView.cpp:252 #, fuzzy msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" "Жанры\tНажмите, чтобы изменить порядок сортировки\tНажмите, чтобы изменить " "порядок сортировки" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" "Исполнители\tНажмите, чтобы изменить порядок сортировки\tНажмите, чтобы " "изменить порядок сортировки" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" "Альбомы\tНажмите, чтобы изменить порядок сортировки\tНажмите, чтобы изменить " "порядок сортировки" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Настроить столбцы..." #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Просмотреть" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Перемешать\tCtrl-R" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "В обратном порядке" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Все %d жанры" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Все жанры" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Все %d исполнители" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Все %d альбомы" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "По %s" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Сортировать по году выхода альбома" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Столбцы\t\tИзменить видимые столбцы." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "Сор&тировка\t\tИзменить сортировку." #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "Воспроизвести" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "Остановить" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Предыдущий трек" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Следующий трек" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Воспроизвести\tНачать воспроизведение\tНачать воспроизведение" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Пауза\tПауза\tПриостановить воспроизведение" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Остановить\tОстановить воспроизведение\tОстановить воспроизведение" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "" "Предыдущий\tВоспроизвести предыдущий трек\tВоспроизвести предыдущий трек." #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Следующий\tВоспроизвести следующий трек\tВоспроизвести следующий трек." #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Музыка" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" "Импортировать папку...\tCtrl-O\tИмпортировать музыку из папки в библиотеку" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "" "Синхронизировать папку...\t\tСинхронизировать папку с музыкой и библиотеку" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "Вы&ход\tCtrl-Q\tВыход из приложения." #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "Р&едактировать" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Копировать\tCtrl-C\tКопировать выделенные треки" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "&Вырезать\tCtrl-X\tВырезать выделенные треки" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "Вст&авить\tCtrl-V\tВставить из буфера обмена" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Найти...\tCtrl-F\tПоказать фильтр поиска." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Опции" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Вид" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "" "&Просмотреть\tCtrl-B\tПоказать браузер по жанрам, исполнителям и альбомам." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "Показать &жанры\tCtrl-G\tПоказать браузер жанров." #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Показать &источники\tCtrl-S\tПоказать браузер источников " #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "" "Показать в полноэкранном режиме\tF12\tПереключить в полноэкранный режим." #: src/GMWindow.cpp:296 #, fuzzy msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Показать мини-плеер\tF11\tПерключиться на мини-плеер" #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Сортировать" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "&Перейти на проигрываемый трек\tCtrl-J\tПоказать проигрываемый трек." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Управление" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Воспроизвести\tCtrl-P\tНачать воспроизведение." #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Остановить\tCtrl-\\\tОстановить воспроизведение." #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Предыдущий трек\tCtrl-[\tВоспроизвести предыдущий трек." #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Следующий трек\tCtrl-]\tВоспроизвести следующий трек." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Выключить повтор\tCtrl-,\tПовтор текущего трека." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Повторять трек\tCtrl-.\tПовтор текущего трека." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Повторять все треки\tCtrl-/\tПовтор всех треков." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Повторять A-B\tCtrl-T\tПовторять часть трека." #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Случайный режим\tAlt-R\tВоспроизводить треки в случайном порядке." #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Эквалайзер\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Таймер выключения\t\tУстановить таймер выключения." #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Справка" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Домашняя страница" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "Со&общить об ошибке..." #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Зарегистрироваться на last.fm..." #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" "Присоединиться к GMM на last.fm...\t\tПрисоединиться к группе Goggles Music " "Manager group на last.fm..." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&О программе" #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "Пауза" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Предыдущий" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Следующий" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 #, fuzzy msgid "Start playback." msgstr "Воспроизвести\tCtrl-P\tНачать воспроизведение." #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 #, fuzzy msgid "Start playback" msgstr "Воспроизвести\tCtrl-P\tНачать воспроизведение." #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 #, fuzzy msgid "Pause playback." msgstr "Пауза\t\tПриостановить воспроизведение." #: src/GMWindow.cpp:935 #, fuzzy msgid "Pause playback" msgstr "Пауза\t\tПриостановить воспроизведение." #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Повтор A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Повтор А" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "" #: src/GMWindow.cpp:1206 #, fuzzy msgid "…" msgstr "Редактировать..." #: src/GMWindow.cpp:1212 #, fuzzy msgid "Select File" msgstr "Выбрать все" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Таймер выключения" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Установить таймер выключения" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Остановить воспроизведение через заданное время" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Запустить таймер" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Выключить через" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "часов и" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "минут." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Музыкальная библиотека" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Интернет радио" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "В&ыход" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Пропустить" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Пропустить &все" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Не сохранять" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tВыбрать цвет" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tТон, насыщенность, величина" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tКрасный, зеленый, синий" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Красный:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Зеленый:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Синий:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Прозрачность:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Тон:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Насыщенность:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Величина:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Прозрачность:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tГолубой, пурпурный, желтый" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Голубой:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Пурпурный:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Желтый:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tПо имени" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Создать новую папку" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Уже существует" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Невозможно создать" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Копировать файла" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Ошибка при копировании файла" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Переместить файл" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Ошибка при перемещении файла" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Создать файловую ссылку" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Ошибка создания файловой ссылки" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Удаление файлов" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Ошибка удаления файлов" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Перейти на уровень выше" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Домашняя папка" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Рабочая папка" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Сортировка" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Игнорировать регистр" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Скрытые файлы" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Закладки" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Установить закладку" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Очистить закладки" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Новая папка..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Копировать..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Переместить..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Ссылка..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Удалить..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Дата изменения" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Пользователь" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Группа" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Атрибуты" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Ссылка" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Создать новую папку с именем: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "Файл или папка %s уже существует.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Невозможно создать папку %s.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Копировать файл из:\n" "\n" "%s\n" "\n" "в: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Невозможно скопировать файл:\n" "\n" "%s to: %s\n" "\n" "Продолжить?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Переместить файл из:\n" "\n" "%s\n" "\n" "в: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Невозможно переместить файл:\n" "\n" "%s to: %s\n" "\n" "Продолжить?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Создать ссылку на файл из:\n" "\n" "%s\n" "\n" "в: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Невозможно создать ссылку на файл:\n" "\n" "%s в: %s\n" "\n" "Продолжить?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Удаление файлов" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Вы уверены, что хотите удалить файл:\n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "Невозможно удалить файл:\n" "\n" "%s\n" "\n" "Продолжить?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Выбрать все" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Сортировать по" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Вид" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Мелкие значки" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Крупные значки" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Детали" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Строки" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Столбцы" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Предпросмотр изображений" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Нормальные изображения" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Средние изображения" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Огромные изображения" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Заменить" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "За&менить все" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "&Найти:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Заменить &на:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "&Точно" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Игнорировать регистр" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "В&ыражение" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "В &обратном порядке" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Найти" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Готово." #~ msgid "Old Name" #~ msgstr "Прежнее имя" #~ msgid "New Name" #~ msgstr "Новое имя" #~ msgid "Pitch:" #~ msgstr "Высота:" #~ msgid "Any" #~ msgstr "Любая" #~ msgid "Fixed" #~ msgstr "Фиксированная" #~ msgid "Variable" #~ msgstr "Переменная" #, fuzzy #~ msgid " Type:" #~ msgstr "Тип" #, fuzzy #~ msgid "Scalable" #~ msgstr "Масштабируемая" #, fuzzy #~ msgid "Size:" #~ msgstr "Размер" #, fuzzy #~ msgid "Family:" #~ msgstr "Се&мейство:" #~ msgid "Always Show Remote" #~ msgstr "Всегда показывать мини окно" #~ msgid "Source\tActive Source Color" #~ msgstr "Источник\tЦвет активного источника" #~ msgid "About" #~ msgstr "О программе" #~ msgid "" #~ "An incompatible version of SQLite (%s) is being used.\n" #~ "Goggles Music Manager requires at least SQLite 3.3.8.\n" #~ "Please upgrade your SQLite installation." #~ msgstr "" #~ "Используется несовместимая версия SQLite (%s)\n" #~ "Goggles Music Manager требует SQLite 3.3.8. или выше.\n" #~ "Пожалуйста, обновите Вашу версию SQLite." #~ msgid "" #~ "This version of SQLite (%s) is broken.\n" #~ "Please upgrade your SQLite installation to at least 3.6.3." #~ msgstr "" #~ "Эта версия SQLite (%s) повреждена. \n" #~ "Пожалуйста, обновите Вашу версию SQLite до 3.6.3 или выше." #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "&Присоединиться к GMM на last.fm...\tПрисоединиться к группе Goggles " #~ "Music Manager на last.fm...\tПрисоединиться к группе Goggles Music " #~ "Manager на last.fm..." #~ msgid "Font" #~ msgstr "Шрифт" #~ msgid "Theme Directory:" #~ msgstr "Папка темы:" #~ msgid "Select Theme Directory" #~ msgstr "Выбрать папку тем" #~ msgid "thin" #~ msgstr "тонкий" #~ msgid "normal" #~ msgstr "нормальный" #~ msgid "bold" #~ msgstr "жирный" #~ msgid "regular" #~ msgstr "нормальный" #~ msgid "&Weight:" #~ msgstr "&Толщина:" #~ msgid "&Style:" #~ msgstr "&Стиль:" #~ msgid "Si&ze:" #~ msgstr "Ра&змер" #~ msgid "Character Set:" #~ msgstr "Кодировка:" #~ msgid "West European" #~ msgstr "Западно-европейская" #~ msgid "East European" #~ msgstr "Восточно-европейская" #~ msgid "South European" #~ msgstr "Юго-европейская" #~ msgid "North European" #~ msgstr "Северо-европейская" #~ msgid "Cyrillic" #~ msgstr "Кириллица" #~ msgid "Arabic" #~ msgstr "Арабская" #~ msgid "Greek" #~ msgstr "Греческая" #~ msgid "Hebrew" #~ msgstr "Иврит" #~ msgid "Turkish" #~ msgstr "Турецкая" #~ msgid "Nordic" #~ msgstr "Скандинавская" #~ msgid "Thai" #~ msgstr "Тайская" #~ msgid "Baltic" #~ msgstr "Прибалтийская" #~ msgid "Celtic" #~ msgstr "Celtic" #~ msgid "Russian" #~ msgstr "Русская" #~ msgid "Central European (cp1250)" #~ msgstr "Центрально-европейская (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Кириллица (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Центрально-европейская (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Греческая (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Турецкая (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Иврит (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Арабская (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Прибалтийская (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Вьетнамская (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Тайская (cp874)" #~ msgid "UNICODE" #~ msgstr "Юникод" #~ msgid "Set Width:" #~ msgstr "Задать толщину:" #~ msgid "All Fonts:" #~ msgstr "Все шрифты:" #~ msgid "Preview:" #~ msgstr "Предпросмотр:" #, fuzzy #~ msgid "Import Playlist…\t\tImport a existing playlist" #~ msgstr "Новый плейлист...\t\tСоздать новый плейлист" #~ msgid "Import Files?" #~ msgstr "Импортировать файлы?" #~ msgid "" #~ "Would you like import the pasted files and/or directories into the Music " #~ "Library?" #~ msgstr "" #~ "Хотите ли Вы импортировать скопированные файлы и/или директории в " #~ "музыкальную библиотеку?" #~ msgid "Yes" #~ msgstr "Да" #~ msgid "Edit…\tF2\tEdit Genre." #~ msgstr "Редактировать...\tF2\tРедактировать жанр." #~ msgid "Edit…\tF2\tEdit Artist." #~ msgstr "Редактировать...\tF2\tРедактировать исполнителя." #~ msgid "Edit…\tF2\tEdit Album." #~ msgstr "Редактировать...\tF2\tРедактировать альбом." #~ msgid "" #~ "%s\n" #~ "by: %s\n" #~ "from: %s" #~ msgstr "" #~ "%s\n" #~ "по: %s\n" #~ "из: %s" #~ msgid "Now Playing" #~ msgstr "Проигрывается" #~ msgid "Start Up:" #~ msgstr "Запуск:" #~ msgid "Show Main Window" #~ msgstr "Показать основное окно" #~ msgid "Show Mini Remote" #~ msgstr "Показать мини окно" #~ msgid "Previous View" #~ msgstr "Предыдущий вид" #~ msgid "P&ause" #~ msgstr "&Пауза" #~ msgid "\tPause\tPause Playback" #~ msgstr "\tПриостановить\tПриостановить воспроизведение" #~ msgid "Open URL…\t\tOpen Stream or File" #~ msgstr "Открыть URL...\t\tОткрыть поток или файл" #~ msgid "Open MRL" #~ msgstr "Открыть MRL" #~ msgid "A capella" #~ msgstr "A capella" #~ msgid "Acid" #~ msgstr "Acid" #~ msgid "Acid Jazz" #~ msgstr "Acid Jazz" #~ msgid "Acid Punk" #~ msgstr "Acid Punk" #~ msgid "Acoustic" #~ msgstr "Acoustic" #~ msgid "Alternative" #~ msgstr "Alternative" #~ msgid "AlternRockAmbient" #~ msgstr "AlternRockAmbient" #~ msgid "Avantgarde" #~ msgstr "Avantgarde" #~ msgid "Ballad" #~ msgstr "Ballad" #~ msgid "Bass" #~ msgstr "Bass" #~ msgid "Bebob" #~ msgstr "Bebob" #~ msgid "Big Band" #~ msgstr "Big Band" #~ msgid "Blues" #~ msgstr "Blues" #~ msgid "Bluegrass" #~ msgstr "Bluegrass" #~ msgid "Booty Bass" #~ msgstr "Booty Bass" #~ msgid "Cabaret" #~ msgstr "Cabaret" #~ msgid "Chamber Music" #~ msgstr "Chamber Music" #~ msgid "Chanson" #~ msgstr "Chanson" #~ msgid "Chorus" #~ msgstr "Chorus" #~ msgid "Christian Rap" #~ msgstr "Christian Rap" #~ msgid "Classical" #~ msgstr "Classical" #~ msgid "Classic Rock" #~ msgstr "Classic Rock" #~ msgid "Club" #~ msgstr "Club" #~ msgid "Comedy" #~ msgstr "Comedy" #~ msgid "Country" #~ msgstr "Country" #~ msgid "Cult" #~ msgstr "Cult" #~ msgid "Dance" #~ msgstr "Dance" #~ msgid "Dance Hall" #~ msgstr "Dance Hall" #~ msgid "Darkwave" #~ msgstr "Darkwave" #~ msgid "Death Metal" #~ msgstr "Death Metal" #~ msgid "Disco" #~ msgstr "Disco" #~ msgid "Dream" #~ msgstr "Dream" #~ msgid "Drum Solo" #~ msgstr "Drum Solo" #~ msgid "Duet" #~ msgstr "Duet" #~ msgid "Easy Listening" #~ msgstr "Easy Listening" #~ msgid "Electronic" #~ msgstr "Electronic" #~ msgid "Ethnic" #~ msgstr "Ethnic" #~ msgid "Euro-Dance" #~ msgstr "Euro-Dance" #~ msgid "Euro-House" #~ msgstr "Euro-House" #~ msgid "Euro-Techno" #~ msgstr "Euro-Techno" #~ msgid "Fast Fusion" #~ msgstr "Fast Fusion" #~ msgid "Folk" #~ msgstr "Folk" #~ msgid "Folk-Rock" #~ msgstr "Folk-Rock" #~ msgid "Folklore" #~ msgstr "Folklore" #~ msgid "Freestyle" #~ msgstr "Freestyle" #~ msgid "Funk" #~ msgstr "Funk" #~ msgid "Fusion" #~ msgstr "Fusion" #~ msgid "Game" #~ msgstr "Game" #~ msgid "Gangsta" #~ msgstr "Gangsta" #~ msgid "Gospel" #~ msgstr "Gospel" #~ msgid "Gothic" #~ msgstr "Gothic" #~ msgid "Gothic Rock" #~ msgstr "Gothic Rock" #~ msgid "Grunge" #~ msgstr "Grunge" #~ msgid "Hard Rock" #~ msgstr "Hard Rock" #~ msgid "Hip-Hop" #~ msgstr "Hip-Hop" #~ msgid "House" #~ msgstr "House" #~ msgid "Humour" #~ msgstr "Humour" #~ msgid "Industrial" #~ msgstr "Industrial" #~ msgid "Instrumental" #~ msgstr "Instrumental" #~ msgid "Instrumental Pop" #~ msgstr "Instrumental Pop" #~ msgid "Instrumental Rock" #~ msgstr "Instrumental Rock" #~ msgid "Jazz" #~ msgstr "Jazz" #~ msgid "Jazz+Funk" #~ msgstr "Jazz+Funk" #~ msgid "Jungle" #~ msgstr "Jungle" #~ msgid "Latin" #~ msgstr "Latin" #~ msgid "Lo-Fi" #~ msgstr "Lo-Fi" #~ msgid "Meditative" #~ msgstr "Meditative" #~ msgid "Metal" #~ msgstr "Metal" #~ msgid "Musical" #~ msgstr "Musical" #~ msgid "National Folk" #~ msgstr "National Folk" #~ msgid "Native American" #~ msgstr "Native American" #~ msgid "New Age" #~ msgstr "New Age" #~ msgid "New Wave" #~ msgstr "New Wave" #~ msgid "Noise" #~ msgstr "Noise" #~ msgid "Oldies" #~ msgstr "Oldies" #~ msgid "Opera" #~ msgstr "Opera" #~ msgid "Other" #~ msgstr "Other" #~ msgid "Polka" #~ msgstr "Polka" #~ msgid "Pop" #~ msgstr "Pop" #~ msgid "Pop-Folk" #~ msgstr "Pop-Folk" #~ msgid "Pop/Funk" #~ msgstr "Pop/Funk" #~ msgid "Porn Groove" #~ msgstr "Porn Groove" #~ msgid "Power Ballad" #~ msgstr "Power Ballad" #~ msgid "Pranks" #~ msgstr "Pranks" #~ msgid "Primus" #~ msgstr "Primus" #~ msgid "Progressive Rock" #~ msgstr "Progressive Rock" #~ msgid "Psychadelic" #~ msgstr "Psychadelic" #~ msgid "Psychedelic Rock" #~ msgstr "Psychedelic Rock" #~ msgid "Punk" #~ msgstr "Punk" #~ msgid "Punk Rock" #~ msgstr "Punk Rock" #~ msgid "R&B" #~ msgstr "R&B" #~ msgid "Rap" #~ msgstr "Rap" #~ msgid "Rave" #~ msgstr "Rave" #~ msgid "Reggae" #~ msgstr "Reggae" #~ msgid "Retro" #~ msgstr "Retro" #~ msgid "Revival" #~ msgstr "Revival" #~ msgid "Rhythmic Soul" #~ msgstr "Rhythmic Soul" #~ msgid "Rock" #~ msgstr "Rock" #~ msgid "Rock & Roll" #~ msgstr "Rock & Roll" #~ msgid "Samba" #~ msgstr "Samba" #~ msgid "Satire" #~ msgstr "Satire" #~ msgid "Showtunes" #~ msgstr "Showtunes" #~ msgid "Ska" #~ msgstr "Ska" #~ msgid "Slow Jam" #~ msgstr "Slow Jam" #~ msgid "Slow Rock" #~ msgstr "Slow Rock" #~ msgid "Sonata" #~ msgstr "Sonata" #~ msgid "Soul" #~ msgstr "Soul" #~ msgid "Soundtrack" #~ msgstr "Soundtrack" #~ msgid "Sound Clip" #~ msgstr "Sound Clip" #~ msgid "Southern Rock" #~ msgstr "Southern Rock" #~ msgid "Space" #~ msgstr "Space" #~ msgid "Speech" #~ msgstr "Speech" #~ msgid "Swing" #~ msgstr "Swing" #~ msgid "Symphonic Rock" #~ msgstr "Symphonic Rock" #~ msgid "Symphony" #~ msgstr "Symphony" #~ msgid "Tango" #~ msgstr "Tango" #~ msgid "Techno" #~ msgstr "Techno" #~ msgid "Techno-Industrial" #~ msgstr "Techno-Industrial" #~ msgid "Top 40" #~ msgstr "Top 40" #~ msgid "Trailer" #~ msgstr "Trailer" #~ msgid "Trance" #~ msgstr "Trance" #~ msgid "Tribal" #~ msgstr "Tribal" #~ msgid "Trip-Hop" #~ msgstr "Trip-Hop" #~ msgid "Vocal" #~ msgstr "Vocal" gogglesmm-0.12.7/po/fr.po0000644000175000001440000022162611524673460013713 0ustar sxjusersmsgid "" msgstr "" "Project-Id-Version: Goggles Music Manager\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: \n" "Last-Translator: Erwan Inyzant \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: French\n" "X-Poedit-Country: FRANCE\n" "X-Language: fr_FR\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Fermer" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Configurer les Colonnes" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Accepter" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Annuler" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "Choisissez l'ordre d'apparition des informations dans le track-list." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Vers le Haut" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Vers le Bas" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Modèle Invalide" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" "Le Modèle utilisé est invalide. Le titre du morceau %%T doit être spécifié.\n" "Modifiez le modèle du nom de fichier dans les préférences." #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Erreur de base de donnée" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Oups. Erreur de Base de donnée" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Aucuns changements" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Le nom des fichiers n'ont eu besoin d'aucuns changements" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Renommer les Fichiers Audio ?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Renommage des Fichiers Audio..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "Les fichier audio suivant vont être renommés" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "&Renommer" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Impossible de renommer le fichier" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "Impossible de renommer:\n" "%s\n" "\n" "en:%s\n" "Continuer à renommer les fichiers ?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "Impossible de renommer:\n" "%s\n" "\n" "en:%s" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Modèle du Nom de Fichier" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "Pour les Modèles vous pouvez utiliser des chemins relatifs ou absolus, \n" "des variables d'environnements et le caractère ~. Les chemins relatifs\n" "sont calculés par rapport à l'emplacement du fichier original. L'extension\n" "est récupérée automatiquement. Les macros suivantes peuvent être\n" "utilisées:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - titre %A - nom de l'album\n" "%P - nom de l'artiste pour l'album %p - nom de l'artiste pour la " "piste\n" "%y - annee %d - numéro du disque\n" "%N - numéro de la piste (2 chiffres) %n - numéro de la piste \n" "%G - genre" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Modèle:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Encodage:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Exclure:" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Options:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Remplacer les espaces par des underscores" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Minuscule" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Extension minuscule" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "No." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Queue" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Titre" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Artiste" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Artiste de l'Album" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Album" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Disque" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Genre" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Année" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Durée" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Supprimer...\tSuppr\tSupprimer le Genre de la Bibliothèque." #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Copier\tCtrl-C\tCopier les morceaux associés dans le presse papier." #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "" "Supprimer...\tSuppr\tSupprimer les morceaux associés de la bibliothèque." #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Editer...\tF2\tEditer les Informations sur le morceau." #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Copier\tCtrl-C\tCopier le(s) morceau(x) dans le presse papier." #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Supprimer...\tSuppr\tSupprimer le(s) morceau(x) de la bibliothèque." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Nouvelle Playliste...\t\tCréer une nouvelle playliste." #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Exporter..." #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Information...\t\tStatistiques sur la Bibliothèque" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "" "Supprimer Toutes les Pistes\t\tSupprimer toutes les pistes de la bibliothèque" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Modifier les Informations de la Piste" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Sauver" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Propriétés" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Nom du Fichier" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Type" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Taille" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Bitrate" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Echantillonnage" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Cannaux" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Piste" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tArtistes Différents" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tMêmes Artistes" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Récupération auto des N° de pistes. Offset:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Mettre à Jour les Tags dans le Fichier" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Mettre à jour le Nom du Fichier" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Gérer le modèle d'export..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Mise à Jour des Tags? " #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Aucun morceau n'a été mis à jour.\n" "Voulez vous toujours écrire les tags pour les morceaux sélectionnés?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Supprimer les Fichiers Audio ?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Supprimer les Fichiers Audio..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Les fichiers audio suivant vont être supprimer" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Supprimer" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Exporter la Bibliothèque Principale" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Exporter la Play Liste" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Ecraser ce fichier ?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "Le fichier existe déjà. Voulez vous l'écraser ?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Exporter les Genres" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Exporter les morceaux de ce genre dans le répertoire de destination." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Exporter les Artistes" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "" "Exporter les morceaux de cet artiste vers le répertoire de destination." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Exporter les Albums" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Exporter les morceaux de cet album vers le répertoire de destination." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Exporter les morceaux" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Exporter les morceaux vers le répertoire de destination." #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Exporter" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Supprimer le Genre ?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Supprimer tous les morceaux de ce genre de la bibliothèque?" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Supprimer l'Artiste?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Supprimer les morceaux de cet artiste de la bibliothèque?" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Supprimer l'Album?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Supprimer les morceaux de l'album de la bibliothèque?" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Supprimer le(s) les Morceaux ?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Supprimer le(s) morceau(x) de la bibliothèque?" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Supprimer les morceaux du disque" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Erreur sur la Bibliothèque" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "Impossible de supprimer le genre de la bibliothèque" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Impossible de supprimer l'artiste de la bibliothèque" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Impossible de supprimer l'album de la bibliothèque" #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "Impossible de supprimer le morceau de la bibliothèque." #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Créer une Playliste" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Spécifiez le nom de la nouvelle playliste" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Créer" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Nom" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Nouvelle Playliste" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Effacer la Bibliothèque ?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Supprimer tous les morceaux de la bibliothèque?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Tout Supprimer" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Garder les playlistes" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Information sur la Bibliothèque" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Votre collection de musique s'élève à..." #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Pistes:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Artistes:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Albums:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Durée Totale:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Equaliser" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Equaliser:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tSauver" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tReset" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tSupprimer" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Pré-amp" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Désactiver" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Manuel" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Supprimer le Preset" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Etes vous sûr de vouloir supprimer le preset %s?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Nom du Preset" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Entrez le nom du preset:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Ecraser le preset" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "Le preset %s existe déjà. Voules vous l'écraser ?" #: src/GMFontDialog.cpp:209 #, fuzzy msgid "Ultra Condensed" msgstr "Ultra condensé" #: src/GMFontDialog.cpp:210 #, fuzzy msgid "Extra Condensed" msgstr "Très condensé" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Condensé" #: src/GMFontDialog.cpp:212 #, fuzzy msgid "Semi Condensed" msgstr "Un Peu Condensé" #: src/GMFontDialog.cpp:214 #, fuzzy msgid "Semi Expanded" msgstr "Peu Etendu" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Etendu" #: src/GMFontDialog.cpp:216 #, fuzzy msgid "Extra Expanded" msgstr "Très Etendu" #: src/GMFontDialog.cpp:217 #, fuzzy msgid "Ultra Expanded" msgstr "Ultra Etendu" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 #, fuzzy msgid "Extra Light" msgstr "Très léger" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 #, fuzzy msgid "Light" msgstr "léger" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 #, fuzzy msgid "Medium" msgstr "moyen" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 #, fuzzy msgid "Demibold" msgstr "bien gras" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 #, fuzzy msgid "Extra Bold" msgstr "très gras" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 #, fuzzy msgid "Heavy" msgstr "très gras" #: src/GMFontDialog.cpp:239 #, fuzzy msgid "Reverse Oblique" msgstr "oblique inversé" #: src/GMFontDialog.cpp:240 #, fuzzy msgid "Reverse Italic" msgstr "italique inversé" #: src/GMFontDialog.cpp:242 #, fuzzy msgid "Italic" msgstr "italique" #: src/GMFontDialog.cpp:243 #, fuzzy msgid "Oblique" msgstr "oblique" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normal" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "&Répertoire:" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&Nom du Fichier:" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "F&iltre de fichier:" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Lecture Seule" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Répertoire:" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "&Créer un signet\t\tCréer un signet pour le répertoire courant." #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "&Effacer les bookmarks\t\tEffacer les bookmarks." #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "" "\tRemonter d'un répertoire\tRemonter d'un répertoire dans l'arborescence." #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tAller au répertoire utilisateur\tRevenir au répertoire utilisateur." #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tAller au répertoire de travail\tRevenir au répertoire de travail." #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tSignets\tParcourir les répertoires signés." #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tCréer un nouveau répertoire\tCréer un nouveau répertoire." #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tAfficher en liste\tAfficher les répertoires avec de petites icônes." #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tAfficher en icônes\tAfficher les répertoires avec de grosses icônes." #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tAfficher en détails\tAfficher une liste détaillée des répertoires." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "" "\tAfficher les fichiers cachés\tAfficher les fichiers et répertoires cachés." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "" "\tMasquer les Fichiers Cachés\tMasquer les fichiers et les répertoires " "cachés." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Synchroniser les répertoires" #: src/GMImportDialog.cpp:414 #, fuzzy msgid "Import Playlist" msgstr "Exporter la Play Liste" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Importer la Musique" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Fichier(s)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Répertoire" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "" "Filtre d'exclusion\tPermet de filtrer les répertoires et/ou les fichiers à " "partir d'un modèle" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Dossiers:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Fichiers:" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Sync" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Opération de Synchro" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" "Importer de nouveaux morceaux\tImporte les fichiers qui ne sont pas encore " "dans la base de données." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Enlever les morceaux qui ont été supprimé du disque" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Mettre à jour les morceaux existant :" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" "Modifiés depuis l'import\tRelit les tags seulement si le fichier a été " "modifié." #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Tout\tToujours lire les tags" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Supprimer de la base de données les morceaux trouvés dans les dossiers" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Piste" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Paramètres d'analyse" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Analyser les infos depuis:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Tag" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Les deux" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Valeur par défaut:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Numéro des pistes selon l'ordre d'analyse." #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - Titre %P - nom de l'artiste pour l'album\n" "%p - nom de l'artiste du morceau %A - nom de l'album\n" "%N - numéro du morceau %G - genre" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Remplacer les underscores par des espaces" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Importer" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Impossible d'initialiser le driver audio." #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Hôte inconnu." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Périphérique inconnu" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Réseau introuvable." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Sorties Audio indisponibles." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Connection Refusée." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Fichier introuvable." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Ressource inaccessible. Vérifiez les permissions" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Erreur de Lecture" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Erreur pendant le chargement de la librairie/plugin" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Attention" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Attention Problème de Sécurité" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Erreur Inconnue" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Erreur" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Impossible de créer le répertoire %s\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Pour une raison inconnue la librairie FOX n'a pas été compilé avec le " "support de PNG.\n" "Afin de permettre à Goggles Music Manager d'afficher de petites icônes, la " "librairie FOX\n" "doit supporter PNG. Si vous avez compilé FOX par vous-même, le header libpng " "ne\n" "devait pas être installé sur votre système." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "" "Le bus de session est indisponible. Toutes les fonctions qui utilisent dbus " "sont désactivées." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "" "Erreur DBus. Toutes les fonctions qui utilisent le bus de session sont " "désactivées." #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "" "Le bus de session est indisponible. Toutes les fonctions qui utilisent le " "bus de session sont désactivées." #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Erreur sur le Périphérique Audio" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Erreur Last.FM" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Erreur de Lecture" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Supprimer...\tSuppr\tSupprimer le(s) morceau(x) de la playliste." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Modifier..." #: src/GMPlayListSource.cpp:162 #, fuzzy msgid "Import…" msgstr "Exporter..." #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Supprimer la Playliste" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Supprimer tous les morceaux de ce genre de la bibliothèque ?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Supprimer les morceaux de l'artiste de la playliste?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Supprimer les morceaux de l'album de la playliste ?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Supprimer le(s) morceau(x) de la playliste?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Supprimer les morceaux de la bibliothèque" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Modifier la Playliste" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Modifier le nom de la playliste" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Supprimer la Playliste ?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Etes vous sûr de vouloir supprimer la playlist ?" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Oui" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Non" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Préférences" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Général" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Options de Tri" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Ignorer les mots" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Pochettes d'Albums" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" "Afficher la pochette d'album pour le morceau courant\tAfficher la pochette " "d'album pour le morceau courant" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" "Afficher les pochettes d'ablums dans l'explorateur\tAfficher les pochettes " "dl'ablums dans l'explorateur" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "System Tray" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Afficher le Tray Icône\tAfficher le tray icône dans le système tray." #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" "Afficher les notifications de changement de morceau\tInformer le démon de " "notification des changements de morceaux." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "Cette version de Goggles Music Manager\n" "ne gère pas Last-FM. Vous devez installer\n" "un version plus récente de GMM." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 #, fuzzy msgid "&Sign up…" msgstr "&Inscrivez vous sur last.fm..." #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Nom d'Utilisateur:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Mot de passe:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Fenêtre" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Fenêtre" #: src/GMPreferencesDialog.cpp:365 #, fuzzy msgid "Close button minimizes to tray" msgstr "Le bouton de fermeture cache la fenêtre principale" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Afficher la Barre de Statut" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Afficher les Icônes dans l'Explorateur de Pistes" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Affiche le morceau courant dans la barre de titre" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Contrôles du Lecteur" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Position:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Haut" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Bas" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Style:" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Afficher les Libellés" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Grande Icônes" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "A&pparence" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Couleurs" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "fg\tCouleur de premier plan" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "bg\tCouleur d'arrière plan" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt bg\tCouleur Alternative d'Arrière Plan" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normal\tCouleur Normale du Texte" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Base\tCouleur de Base" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Sélection\tCouleur du Texte Sélectionné" #: src/GMPreferencesDialog.cpp:433 #, fuzzy msgid "Menu\tMenu Base Color" msgstr "Menu\tCouleur de Texte du Menu" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menu\tCouleur de Texte du Menu" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Bordure\tCouleur de la Bordure" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Info Bulle\tCouleur de l'Info Bulle" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Surbillance\t Couleur de Surbrillance" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Ombre\tCouleur de l'Ombre" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Lecture\tCouleur de la piste actuellement en lecture" #: src/GMPreferencesDialog.cpp:463 #, fuzzy msgid "Tray\tTray Background Color" msgstr "bg\tCouleur d'arrière plan" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Presets:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 #, fuzzy msgid "Default Font" msgstr "Valeur par défaut:" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Modifier..." #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Icônes" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Audio" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Moteur" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Driver Audio:" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Libérer l'audio à la pause." #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Eteindre le moteur audio à stop." #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" "Lancer le moteur Audio au démarrage.\tAfin que le démarrage soit plus " "rapide, le moteur audio est généralement lancé à la lecture de la première " "piste.\tAfin que le démarrage soit plus rapide, le moteur audio est " "généralement lancé à la lecture de la première piste." #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Playback" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Replay Gain:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Lecture Gapless" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Normalisation du Volume" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "Impossible d'utiliser le driver audio:%s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Courant" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Personnalisé" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Impossible de lancer le navigateur internet" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Selection de la Police" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Next" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "P&revious" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Play" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Stop" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Afficher l'Exploreur" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Quitter" #: src/GMRemote.cpp:385 #, fuzzy msgid "\tShow Browser\tShow Browser" msgstr "Afficher l'Exploreur" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tDémarrer la lecture\tDémarrer la lecture" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tArrêter la Lecture\tArrêter la Lecture" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tJouer le morceau Précédent\tJouer le morceau précédent." #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tJouer le Morceau Suivant\tJouer le Morceau Suivant." #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tAjuster le Volume\tAjuste le Volume" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Impossible d'ouvrir la base de données" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "" "Erreur de la Base de Données : Impossible de récupérer tous les noms de " "fichiers." #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "Impossible de mettre à jour la piste" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Impossible d'ajouter la piste à la base de données" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Erreur Fatale" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Contactez le support si l'erreur se reproduit." #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Mise à Jour de la Base de Données..." #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Veuillez attendre. Cela peut prendre un peu de temps." #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Nouvelles Pistes:" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "Fichier:" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Importation des Fichiers..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "&Arreter l'importation" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" "Sources\tCliquez pour changer l'ordre de tri\tCliquez pour changer l'ordre " "de tri" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Nouvelle Playliste...\t\tCréer une nouvelle playliste" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 #, fuzzy msgid "Import Playlist…\t\tImport existing playlist" msgstr "Nouvelle Playliste...\t\tCréer une nouvelle playliste" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Nouvelle Station Radio...\t\tCréer une nouvelle playliste" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Station" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Nouvelle Station...\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Modifier...\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Supprimer\t\tSupprimer." #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Nouvelle Radio Internet" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Spécifiez l'url et la description de la nouvelle station" #: src/GMStreamSource.cpp:168 #, fuzzy msgid "C&reate" msgstr "&Créer" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "Chemin" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "Description" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Sans-Titre" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Modifier la Radio Internet" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Mettre à jour l'url et la description de la radio" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Supprimer la/les Radio(s) Internet ?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Supprimer la/les Radio(s) Internet de la Bibliothèque ?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Impossible de Supprimer la Radio de la Bibliothèque." #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" "Goggles Music Manager n'a pas réussi à ouvrir la base de donnée.\n" "La base de donnée est peut être corrompue. Supprimez ~/.goggles/goggles.db " "puis essayez à nouveau.\n" "Si l'erreur subsiste, vous pouvez poster un bug sur le site : http://code." "google.com/p/gogglesmm" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tFermer les Filtres\tFermer les Filtres" #: src/GMTrackView.cpp:246 #, fuzzy msgid "&Find" msgstr "Chercher" #: src/GMTrackView.cpp:252 #, fuzzy msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" "Genres\tCliquez pour changer l'ordre de tri\tCliquez pour changer l'ordre de " "tri" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" "Artistes\tCliquez pour changer l'ordre de tri\tCliquez pour changer l'ordre " "de tri" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" "Albums\tCliquez pour changer l'ordre de tri\tCliquez pour changer l'ordre de " "tri" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Configurer les Colonnes..." #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Explorer" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Mélanger\tCtrl-R" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Inverser" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Tous les %d Genres" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Tous les Genres" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Tous les %d Artistes" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Tous les %d Albums" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "Par %s" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Trier par année d'album" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Colonnes\t\tChanger les Colonnes Visibles." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "&Trier\t\tChange le Tri." #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "Play" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "Stop" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Previous Track" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Next Track" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Play\t Démarrer la Lecture\tDémarre la Lecture" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Pause\tPause\tPause dans la lecture" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Stop\tArrêter la Lecture\tArrêter la lecture" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Previous\tJouer la Piste Précédente\tJouer la piste précédente." #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Next\tJouer la Piste Suivante\tJouer la piste suivante." #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Musique" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "Importer...\tCtrl-O\tImporter de la musique dans la Bibliothèque" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "Synchroniser...\t\tSynchroniser les répertoires avec la Bibliothèque" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "&Quitter\tCtrl-Q\t Quitter l'application." #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "&Modifier" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Copier\tCtrl-C\tCopie les Morceaux Sélectionnés" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "&Couper\tCtrl-X\tCoupe les Morceaux Sélectionnés" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "&Coller\tCtrl-V\tColle le Contenu du Presse Papier" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Chercher...\tCtrl-F\tAfficher les filtres de recherche." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Préférences..." #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Affichage" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "&Parcourir\tCtrl-B\tAffiche l'explorateur d'artistes et albums." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "Afficher les &Genres\tCtrl-G\tAfficher l'explorateur de genre." #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Afficher les &Sources\tCtrl-S\tAfficher l'explorateur de sources" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Passer en Plein Ecran\tF12\tPasser en mode plein écran." #: src/GMWindow.cpp:296 #, fuzzy msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Afficher le Mini Lecteur\tF11\tAfficher le Mini Lecteur." #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Trier" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "" "&Revenir au Morceau Courant\tCtrl-J\tAffiche le morceau - album - artiste " "courant." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Contrôles" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Play\tCtrl-P\tDémarre la lecture." #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Stop\tCtrl\\\tArrêter la lecture." #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Morceau Précédent\tCtrl-[\tJouer le morceau précédent." #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Morceau Suivant\tCtrl-]\tJouer le morceau suivant." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Ne pas Répéter\tCtrl-,\tNe pas répéter le morceau courant." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Répéter le morceau\tCtrl-.\tRépète le morceau courant." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Répéter Tous les Morceaux\tCtrl-/\tRépète tous les morceaux." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Répeter A-B\tCtrl-T\tRépete la section du morceau." #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Mode Shuffle\tAlt-R\tJoue les morceaux dans un ordre aléatoire." #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Equaliser\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Minuteur\t\tParamétrer le minuteur." #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Aide" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Page officielle" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "&Rapporter une erreur..." #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Inscrivez vous sur last.fm..." #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" "&Rejoignez GMM sur last.fm...\t\tRejoignez le groupe Goggles Music Manager " "sur last.fm..." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&A Propos..." #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "Pause" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Précédent" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Suivant" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "Démarre la lecture." #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 #, fuzzy msgid "Start playback" msgstr "Démarre la lecture." #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Mettre en Pause." #: src/GMWindow.cpp:935 #, fuzzy msgid "Pause playback" msgstr "Mettre en Pause." #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Répeter A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Répeter A" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 #, fuzzy msgid "Please specify a file or url to play:" msgstr "Veuillez spécifier la MRL à jouer" #: src/GMWindow.cpp:1206 #, fuzzy msgid "…" msgstr "Modifier..." #: src/GMWindow.cpp:1212 #, fuzzy msgid "Select File" msgstr "Tout sélectionner" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Minuteur" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Régler le minuteur" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Arrête la lecture après un laps de temps" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Démarrer le minuteur" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Eteindre dans" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "Heures et" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "minutes." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Bibliothèque" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Radio Internet" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Quitter" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Passer" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "&Tout passer" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Ne pas Sauver" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tChoisir une couleur" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tTeinte, Saturation, Valeur" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tRouge, Vert, Bleu" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Rouge:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Vert:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Bleu:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alpha:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Teinte:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Saturation:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Valeur:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alpha:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tCyan, Magenta, Jaune" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Cyan:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Magenta:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Jaune:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tPar Nom" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Créer un Nouveau Répertoire" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Existe Déjà" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Impossible à Créer" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Copie un Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Erreur en Copiant le Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Déplacer le Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Erreur en Déplaçant le Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Lier le Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Erreur en Liant le Fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Suppression du fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Erreur à la suppression du fichier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Remonter" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Répertoire Home" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Répertoire de travail" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Trier" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Ignorer la casse" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Fichiers cachés" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Bookmark" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Créer un bookmark" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Effacer les bookmarks" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Nouveau Répertoire..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Copier..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Déplacer..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Lier..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Supprimer..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Date modifiée" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Utilisateur" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Groupe" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Attributs" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Lien" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Créer un nouveau répertoire avec le nom :" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "Le fichier ou le répertoire %s existe déjà.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Impossible de créer le répertoire %s.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Copie du fichier depuis:\n" "\n" "%s\n" "\n" "vers :" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Impossible de copier le fichier:\n" "\n" "%s vers %s\n" "\n" "Continuer l'opération?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Déplacer le fichier depuis:\n" "\n" "%s\n" "\n" "vers:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Impossible de déplacer le fichier:\n" "\n" "%s vers: %s\n" "\n" "Continuer l'opération ?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Créer un lien depuis:\n" "\n" "%s\n" "vers :" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Impossible de lier le fichier:\n" "\n" "%s à: %s\n" "\n" "Continuer l'opération ?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Suppression des fichiers" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Etes vous sûr de vouloir supprimer ce fichier ? : \n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "Impossible de supprimer le ficher :\n" "\n" "%s\n" "\n" "Continuer l'opération ?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Tout sélectionner" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Trier par" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Vue" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Petites icônes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Grandes icônes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Détails" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Lignes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Colonnes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Aperçu d'images" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Images Normales" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Images Moyennes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Grandes Images" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Remplacer" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Tout Rem&placer" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "Re&cherche sur:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Remplacer &par:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "Ex&act" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Ignorer la casse" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "E&xpression" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Retour en arrière" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Rechercher" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Prêts." #~ msgid "Old Name" #~ msgstr "Ancien Nom" #~ msgid "New Name" #~ msgstr "Nouveau Nom" #~ msgid "Pitch:" #~ msgstr "Hauteur:" #~ msgid "Any" #~ msgstr "Tout" #~ msgid "Fixed" #~ msgstr "Fixée" #~ msgid "Variable" #~ msgstr "Variable" #, fuzzy #~ msgid " Type:" #~ msgstr "Type" #, fuzzy #~ msgid "Scalable" #~ msgstr "Ajustable:" #, fuzzy #~ msgid "Size:" #~ msgstr "Taille" #, fuzzy #~ msgid "Family:" #~ msgstr "&Famille:" #~ msgid "Always Show Remote" #~ msgstr "Toujours Afficher le Mini Lecteur" #~ msgid "Source\tActive Source Color" #~ msgstr "Source\tCouleur de la Source Active" #~ msgid "About" #~ msgstr "A propos" #~ msgid "" #~ "An incompatible version of SQLite (%s) is being used.\n" #~ "Goggles Music Manager requires at least SQLite 3.3.8.\n" #~ "Please upgrade your SQLite installation." #~ msgstr "" #~ "La version de SQLite (%s) utilisée est incompatible.\n" #~ "Goggles Music Manager utilise une version au moins\n" #~ "équivalente à SQLite 3.3.8. Vous devez mettre à jour\n" #~ "votre installation de SQLite." #~ msgid "" #~ "This version of SQLite (%s) is broken.\n" #~ "Please upgrade your SQLite installation to at least 3.6.3." #~ msgstr "" #~ "Cette version de SQLite (%s) ne fonctionner pas.\n" #~ "Vous devez mettre à jour votre installation de SQLite avec une version au " #~ "moins égale à 3.6.3." #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "&Rejoignez GMM sur last.fm...\tRejoignez le groupe Goggles Music Manager " #~ "sur last.fm...\tRejoignez le groupe Goggles Music Manager sur last.fm..." #~ msgid "Font" #~ msgstr "Police" #~ msgid "Theme Directory:" #~ msgstr "Répertoire du thème:" #~ msgid "Select Theme Directory" #~ msgstr "Selection du Répertoire du Thème" #~ msgid "thin" #~ msgstr "fin" #~ msgid "normal" #~ msgstr "normal" #~ msgid "bold" #~ msgstr "gras" #~ msgid "regular" #~ msgstr "normal" #~ msgid "&Weight:" #~ msgstr "&Epaisseur:" #~ msgid "&Style:" #~ msgstr "&Style:" #~ msgid "Si&ze:" #~ msgstr "Tai&lle:" #~ msgid "Character Set:" #~ msgstr "Encodage:" #~ msgid "West European" #~ msgstr "Europe de l'Ouest" #~ msgid "East European" #~ msgstr "Europe de Est" #~ msgid "South European" #~ msgstr "Europe du Sud" #~ msgid "North European" #~ msgstr "Europe du Nord" #~ msgid "Cyrillic" #~ msgstr "Cyrillique" #~ msgid "Arabic" #~ msgstr "Arabe" #~ msgid "Greek" #~ msgstr "Grèc" #~ msgid "Hebrew" #~ msgstr "Hébreu" #~ msgid "Turkish" #~ msgstr "Turque" #~ msgid "Nordic" #~ msgstr "Nordique" #~ msgid "Thai" #~ msgstr "Thai" #~ msgid "Baltic" #~ msgstr "Baltique" #~ msgid "Celtic" #~ msgstr "Celtic" #~ msgid "Russian" #~ msgstr "Russe" #~ msgid "Central European (cp1250)" #~ msgstr "Europe Centrale (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Russe (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Latin1 (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Grèc (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Turque (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Hébreu (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Arabe (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Baltique (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Vietnam (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Thai (cp874)" #~ msgid "UNICODE" #~ msgstr "UNICODE" #~ msgid "Set Width:" #~ msgstr "Espace:" #~ msgid "All Fonts:" #~ msgstr "Toutes les Polices:" #~ msgid "Preview:" #~ msgstr "Aperçu:" #, fuzzy #~ msgid "Import Playlist…\t\tImport a existing playlist" #~ msgstr "Nouvelle Playliste...\t\tCréer une nouvelle playliste" #~ msgid "Import Files?" #~ msgstr "Importer les Fichiers?" #~ msgid "" #~ "Would you like import the pasted files and/or directories into the Music " #~ "Library?" #~ msgstr "" #~ "Voulez vous importer les fichiers et/ou répertoires insérés, dans la " #~ "bibliothèque?" #~ msgid "" #~ "%s\n" #~ "by: %s\n" #~ "from: %s" #~ msgstr "" #~ "%s\n" #~ "par: %s\n" #~ "depuis: %s" #~ msgid "Now Playing" #~ msgstr "En Lecture" #~ msgid "Open URL…\t\tOpen Stream or File" #~ msgstr "Ouvrir l'URL...\t\tOuvrir un Stream ou un Fichier" #~ msgid "Open MRL" #~ msgstr "Ouvrir une MRL" #~ msgid "P&ause" #~ msgstr "P&ause" #~ msgid "\tPause\tPause Playback" #~ msgstr "\tPause\tMettre la Lecture en Pause" #~ msgid "A capella" #~ msgstr "A capella" #~ msgid "Acid" #~ msgstr "Acid" #~ msgid "Acid Jazz" #~ msgstr "Acid Jazz" #~ msgid "Acid Punk" #~ msgstr "Acid Punk" #~ msgid "Acoustic" #~ msgstr "Acoustic" #~ msgid "Alternative" #~ msgstr "Alternative" #~ msgid "AlternRockAmbient" #~ msgstr "AlternRockAmbient" #~ msgid "Avantgarde" #~ msgstr "Avantgarde" #~ msgid "Ballad" #~ msgstr "Ballad" #~ msgid "Bass" #~ msgstr "Bass" #~ msgid "Bebob" #~ msgstr "Bebob" #~ msgid "Big Band" #~ msgstr "Big Band" #~ msgid "Blues" #~ msgstr "Blues" #~ msgid "Bluegrass" #~ msgstr "Bluegrass" #~ msgid "Booty Bass" #~ msgstr "Booty Bass" #~ msgid "Cabaret" #~ msgstr "Cabaret" #~ msgid "Chamber Music" #~ msgstr "Chamber Music" #~ msgid "Chanson" #~ msgstr "Chanson" #~ msgid "Chorus" #~ msgstr "Chorus" #~ msgid "Christian Rap" #~ msgstr "Christian Rap" #~ msgid "Classical" #~ msgstr "Classical" #~ msgid "Classic Rock" #~ msgstr "Classic Rock" #~ msgid "Club" #~ msgstr "Club" #~ msgid "Comedy" #~ msgstr "Comedy" #~ msgid "Country" #~ msgstr "Country" #~ msgid "Cult" #~ msgstr "Cult" #~ msgid "Dance" #~ msgstr "Dance" #~ msgid "Dance Hall" #~ msgstr "Dance Hall" #~ msgid "Darkwave" #~ msgstr "Darkwave" #~ msgid "Death Metal" #~ msgstr "Death Metal" #~ msgid "Disco" #~ msgstr "Disco" #~ msgid "Dream" #~ msgstr "Dream" #~ msgid "Drum Solo" #~ msgstr "Drum Solo" #~ msgid "Duet" #~ msgstr "Duet" #~ msgid "Easy Listening" #~ msgstr "Easy Listening" #~ msgid "Electronic" #~ msgstr "Electronic" #~ msgid "Ethnic" #~ msgstr "Ethnic" #~ msgid "Euro-Dance" #~ msgstr "Euro-Dance" #~ msgid "Euro-House" #~ msgstr "Euro-House" #~ msgid "Euro-Techno" #~ msgstr "Euro-Techno" #~ msgid "Fast Fusion" #~ msgstr "Fast Fusion" #~ msgid "Folk" #~ msgstr "Folk" #~ msgid "Folk-Rock" #~ msgstr "Folk-Rock" #~ msgid "Folklore" #~ msgstr "Folklore" #~ msgid "Freestyle" #~ msgstr "Freestyle" #~ msgid "Funk" #~ msgstr "Funk" #~ msgid "Fusion" #~ msgstr "Fusion" #~ msgid "Game" #~ msgstr "Game" #~ msgid "Gangsta" #~ msgstr "Gangsta" #~ msgid "Gospel" #~ msgstr "Gospel" #~ msgid "Gothic" #~ msgstr "Gothic" #~ msgid "Gothic Rock" #~ msgstr "Gothic Rock" #~ msgid "Grunge" #~ msgstr "Grunge" #~ msgid "Hard Rock" #~ msgstr "Hard Rock" #~ msgid "Hip-Hop" #~ msgstr "Hip-Hop" #~ msgid "House" #~ msgstr "House" #~ msgid "Humour" #~ msgstr "Humour" #~ msgid "Industrial" #~ msgstr "Industrial" #~ msgid "Instrumental" #~ msgstr "Instrumental" #~ msgid "Instrumental Pop" #~ msgstr "Instrumental Pop" #~ msgid "Instrumental Rock" #~ msgstr "Instrumental Rock" #~ msgid "Jazz" #~ msgstr "Jazz" #~ msgid "Jazz+Funk" #~ msgstr "Jazz+Funk" #~ msgid "Jungle" #~ msgstr "Jungle" #~ msgid "Latin" #~ msgstr "Latin" #~ msgid "Lo-Fi" #~ msgstr "Lo-Fi" #~ msgid "Meditative" #~ msgstr "Meditative" #~ msgid "Metal" #~ msgstr "Metal" #~ msgid "Musical" #~ msgstr "Musical" #~ msgid "National Folk" #~ msgstr "National Folk" #~ msgid "Native American" #~ msgstr "Native American" #~ msgid "New Age" #~ msgstr "New Age" #~ msgid "New Wave" #~ msgstr "New Wave" #~ msgid "Noise" #~ msgstr "Noise" #~ msgid "Oldies" #~ msgstr "Oldies" #~ msgid "Opera" #~ msgstr "Opera" #~ msgid "Other" #~ msgstr "Other" #~ msgid "Polka" #~ msgstr "Polka" #~ msgid "Pop" #~ msgstr "Pop" #~ msgid "Pop-Folk" #~ msgstr "Pop-Folk" #~ msgid "Pop/Funk" #~ msgstr "Pop/Funk" #~ msgid "Porn Groove" #~ msgstr "Porn Groove" #~ msgid "Power Ballad" #~ msgstr "Power Ballad" #~ msgid "Pranks" #~ msgstr "Pranks" #~ msgid "Primus" #~ msgstr "Primus" #~ msgid "Progressive Rock" #~ msgstr "Progressive Rock" #~ msgid "Psychadelic" #~ msgstr "Psychadelic" #~ msgid "Psychedelic Rock" #~ msgstr "Psychedelic Rock" #~ msgid "Punk" #~ msgstr "Punk" #~ msgid "Punk Rock" #~ msgstr "Punk Rock" #~ msgid "R&B" #~ msgstr "R&B" #~ msgid "Rap" #~ msgstr "Rap" #~ msgid "Rave" #~ msgstr "Rave" #~ msgid "Reggae" #~ msgstr "Reggae" #~ msgid "Retro" #~ msgstr "Retro" #~ msgid "Revival" #~ msgstr "Revival" #~ msgid "Rhythmic Soul" #~ msgstr "Rhythmic Soul" #~ msgid "Rock" #~ msgstr "Rock" #~ msgid "Rock & Roll" #~ msgstr "Rock & Roll" #~ msgid "Samba" #~ msgstr "Samba" #~ msgid "Satire" #~ msgstr "Satire" #~ msgid "Showtunes" #~ msgstr "Showtunes" #~ msgid "Ska" #~ msgstr "Ska" #~ msgid "Slow Jam" #~ msgstr "Slow Jam" #~ msgid "Slow Rock" #~ msgstr "Slow Rock" #~ msgid "Sonata" #~ msgstr "Sonata" #~ msgid "Soul" #~ msgstr "Soul" #~ msgid "Soundtrack" #~ msgstr "Soundtrack" #~ msgid "Sound Clip" #~ msgstr "Sound Clip" #~ msgid "Southern Rock" #~ msgstr "Southern Rock" #~ msgid "Space" #~ msgstr "Space" #~ msgid "Speech" #~ msgstr "Speech" #~ msgid "Swing" #~ msgstr "Swing" #~ msgid "Symphonic Rock" #~ msgstr "Symphonic Rock" #~ msgid "Symphony" #~ msgstr "Symphony" #~ msgid "Tango" #~ msgstr "Tango" #~ msgid "Techno" #~ msgstr "Techno" #~ msgid "Techno-Industrial" #~ msgstr "Techno-Industrial" #~ msgid "Top 40" #~ msgstr "Top 40" #~ msgid "Trailer" #~ msgstr "Trailer" #~ msgid "Trance" #~ msgstr "Trance" #~ msgid "Tribal" #~ msgstr "Tribal" #~ msgid "Trip-Hop" #~ msgstr "Trip-Hop" #~ msgid "Vocal" #~ msgstr "Vocal" #~ msgid "Start Up:" #~ msgstr "Démarrage:" #~ msgid "Show Main Window" #~ msgstr "Afficher la Fenêtre Principale" #~ msgid "Show Mini Remote" #~ msgstr "Afficher le Mini Lecteur" #~ msgid "Previous View" #~ msgstr "Vue Précédente" #~ msgid "Configure Columns…" #~ msgstr "Configurer les Colonnes..." gogglesmm-0.12.7/po/hu.mo0000644000175000001440000011462012063217121013673 0ustar sxjusers,<H(I((f(((+((-(0$)1U)5)) )!))*-*?*G*N*T*f*1v*5*-*. +;+Z+w+zF,7, ,- -- -$-3+-_-"g--!---!--- . '. 3.?.E. M.Y.b.k.s. y. ..K.9./%/+///'3/[/a/"g/// //////*//00#0 :0G0 M0Z0`0g0m0u0Wz0F0 1%1 +1 81BE111 11 1 1111*2-)3-W33C33 33 344:4 J4T4 \4f4z44444 444 44<4+5@5P5m5t5 |555545'6 )6+36_6g6|6 666661677 $7 27 <7J7 Y7e7 m7x77"7 77 777 7"8 +858 <8 F8 R8]8c8v888"88C89&9 /9=9 L9Y9m9 ~92939'92: N:)X: : :4::%:; ;;%(;N;"U;x;;<< <<= ===== ==== 1>>>,N>8{>> >">>?? $? 0?>? F?T? Y?+c??? ? ???? ?? ?O @ [@ e@o@+w@@ @@@@@) A 4A&AA+hAA AAA%A A&A BW*BBBB BBBBBB BCC !C+C1CLC[CkCpC"CCCCCC% D#3DWD _DkD9zD DDDD1DE&"EIEOE TE aE lEvE}E E5EEEE F.F!GFiFyF)FFF+F&G(EG'nG)GG G.G&(H(OH(xH4H+H-I0IDI\I eI*pI+I'I)IJ(JHJ hJ*uJJJ J J JJ JJ K KJ)KDtK KK%KLL')L)QL {L,LL LLLL1:MClMEMM/N5N :N DNPNoN xN NNNNCN N*ODOSOcOkOpO O#OO8OPP 2P>PBP Q1'Q1YQQlRRRRR RRRR!RRS;ST4'T"\T(TT;T;U[6[\ '\ 1\?\H\a\Ft\R\K]<Z]]6]]{^Y_u____ __I__1_1`,9`f` ~`.` `.` ` aa a ,a :a Fa Qa^a faraza aRaTaEb LbYb^b2bb b b)bb bb ccc)c 2cGk4Vkk"k kkk3l ;lElLlSl4cllll llmm m +m7m@mAFm m)mm!mmn; n \ngnxnnnnnn#no3-oaoXioo ooopp:pXp4np8p#p5q6q+Fq rqq-qq*qr rr$r=r2Fr yr0rss sstu$u;uMuTu[u$nubuu vH)vfrvvv*w-w >wKw iw uwww w w%wwww wwx x&x6xIx^xxyy#"y FySy fyyyy:yz9z:Qzz zz zMz{:1{l{j}{{{{| '|1|I|Y|o|||!|||?|!})} 1}*=}Ah} }}}.} ~4)~'^~~~~3~~ ~ C& j/x H^ wG΀4Kk5,2FCaE;H'p.R=BN<G΄??V"υ J7^98І &#=a?x ć ʇׇ"(K"[K~Kʈ10IzCE<9X!Ҋn3]`k^?nŌ,֌  7+A m_w&׍8 7 CPa)g=+ώEIZw~~+1|waّޑ 0=nuD|-;'+.S%ND#<6`96ѕ@9I5Zٖ*4_o &ɗ4/d  ˘ۘ26Lav V^w j%n:tJtmRPql3F fj _P{!&;7 0yF +2)s w/Hm@kC_Mp*9[=?fc|:$oAZ-4NZd R^>kGE\"XIh42zDeML#&QU3y.-}<NGd #aALx~1}c0r)DrC65 v" Y,%>,9pV|*ah'X~/<bK=uSn?(!UlgxWe6Euv$ 88\i 1[5Js{gqb7IKT.@oT]`]OW+BYBzHOS';Q(`i Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Track&View&Window&Yes?c - display a if c is not empty else display b. ?c - display c if not empty A DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAn incompatible (future) version of the database was found. This usually happens when you try to downgrade to a older version of GMM Press OK to continue and reset the database (all information will be lost!). Press Cancel to quit now and leave the database as is.Are you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBookmarksBorder Border ColorBothBottomBrowseBy %sC&reateCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.ColorsColumnsCondensedConditions may be used as well:Configure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Failed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:For some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport PlaylistImport Playlist… Import existing playlistImport new tracks Imports files not yet in the database.Importing Files...Import…Information… Library StatisticsInternet RadioInvalid TemplateKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMedium imagesMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesOffOops. Database ErrorOptions:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playbackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please specify a file or url to play:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseRowsS&earch for:SamplerateSaturation:Security WarningSelect FileSelect Normal FontSelect allSelected Selected Text ColorSession Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playbackStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.This version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTooltip Tooltip ColorTopTotal Time:TrackTracks:Tray Tray Background ColorTurn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.…Project-Id-Version: hu Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2010-08-30 11:52+0200 Last-Translator: Sipos Sándor Language-Team: Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: KBabel 1.11.4 Hangerő beállítása Hangerő beállítása Könyvjelzők A könyvjelzők megtekintése. Név szerint Szűrő bezárása Szűrő bezárása Új könyvtár létrehozása Új könyvtár létrehozása Cián, Magenta, Sárga Saját könyvtár Saját könyvtár. Munkakönyvtár Ugrás a futtatási könyvtárba Egy könyvtárral feljebb Egy könyvtárral feljebb Rejtett fájlok rejtése Ne mutassa a rejtett fájlokat és könyvtárakat. Szín, telítettség, fényerő Szín kiválasztása Következő szám lejátszása Következő szám lejátszása Előző szám lejátszása Előző szám lejátszása Piros, Zöld, Kék Törlés Alapállapot Mentés Különböző előadók Közös előadók Részletek megjelenítése Részletes könvtárlista megjelenítése. Rejtett fájlok megjelenítése Rejtett fájlok és könyvtárak megjelenítése. Ikonok A könyvtár tartalmának megjelenítése nagy ikonok formájában. Lista A könyvtár tartalmának megjelenítése listaként. Lejátszás Lejátszás Lejátszás megállítása Lejátszás megállítása%T - Cím %A - Album címe %P - Album előadója %p - Szám előadója %y - Év %d - lemez száma %N - Zeneszám sorszáma (2 jegy) %n - Zeneszám sorszáma %G - Műfaj%T - cím %A - album cím %P - album előadója %p - szám előadója %N - szám sorszáma %G - műfaj%s Kérem vegye fel a fejlesztővel a kapcsolatot, ha ez a hiba többször is előfordul.&A programról…&Ok&Alfa:&Hang&Visszafelé&Kék:&Böngészés Ctrl-B Műfaj, előadó, album böngésző megjelenítése.&Mégsem&Könyvjelzők törlése Könyvjelzők törlése&Bezár&Oszlopok Látható oszlopok beállítása.Oszlopok &beállítása&Lejátszás&Másolás Ctrl-C Kijelölt fájlok másolása&Létrehozás&Kivágás Ctrl-X Kijelölt fájlok kivágása&KönyvtárKönyvtár:&Nincs mentésSz&erkesztés&Exportálás&File név:&Fájl(ok)&Általános&Zöld:&Segítség&Honlap&Nagybetűérzékeny&Importálás&Csatlakozás a GMM-hez a last.fm-en… Csatlakozás a last.fm GMM csoportjához.&Ugrás az aktuális számra Ctrl-J Az éppen lejátszott számra ugrik a listában.&Fájl&Következő&Nem&OK&Beillesztés Ctrl-V Beillesztés a vágólapról.&Lejátszás&Kilépés&Kilépés Ctrl-Q Kilépés a programból&Piros:&Törlés&Összes eltávolításaÁt&nevezés&CsereHiba &bejelentéseMenté&s&Keresés&Könyvjelző ide Könyvjelző elhelyezése az aktuális könyvtárra.&Feliratkozás last.fm-re…&Kihagyás&RendezésRendezé&s Rendezés beállítása.Időzítő indítá&saÁll&jImportálás megállítá&sa&Szinkronizálás&Szám&Nézet&Ablak&Igen?c - Mutassa a-t, ha c nem üres, egyéb esetekben b-t. ?c - Mutassa c-t, ha az nem üres. DBus hiba keletkezett. A dbus-t igénylő funkciókat kikapcsoltam.&MegjelenésAlbumAlbum előadójaAlbum borítókAlbumok Nyomja meg a sorrend megváltoztatásához Nyomja meg a sorrend megváltoztatásáhozAlbumok:Összes Mindig olvassa be a címkéket (Tag)Az összes (%d db) albumAz összes (%d db) előadóAz összes (%d db) műfajÖsszes műfajAlfa:Már létezikInkompatibilis (jövőbeli verziószámmal rendelkező) adatbázist találtam! Ez általában akkor fordulhat elő, ha a korábban használtnál régebbi GMM változatot telepített. Nyomjon OK-t az adatbázis eldobásához (minden ott tárolt információ elvész) Nyomjon "Mégsem"-et a kilépéshez, az adatbázis meghagyásához.Biztos, hogy törölni akarja a(z) "%s" nevű hangszín beállítást?Biztos, hogy törölni akarja a fájlt: %sBiztos benne, hogy töröljem a lejátszólistát?ElőadóElőadók Nyomja meg a rendezés megváltoztatásához Nyomja meg a rendezés megváltoztatásáhozElőadók:TulajdonságokHangeszköz hibaHangeszközA hangkimenet nem elérhető.Automatikus sorszámozás. Eltolás:Alap Alap színNagy ikonokBitrátaKönyvjelzőkKeret Keret színeMindkettőAljáraBöngészés%s alapján&LétrehozásNem tudtam létrehozniNem tudtam a %s könyvtárat létrehozni. Lejátszólista nevének megváltoztatásaVáltoztatás…CsatornákVálassza ki a zeneszámok listájának rendezési sorrendjét.Töröljük a Zenei gyűjteményt?Könyvjelzők törléseZárja le a hangeszközt szünetreSzínekOszlopoSűrűFeltételek is alkalmazhatók:Oszlopok beállításaKapcsolódás visszautasítva.Másolás Ctrl-C A kijelölt számok másolása a vágólapra.Másolás Ctrl-C Szám(ok) másolása a vágólapra.Fájl másolásaFájl másolása innen: %s ide: Másolás...Új könyvtár létrehozásaLejátszólista létrehozásaÚj könyvtár létrehozása a következő névvel:AktuálisEgyediCián:Adatbázis hibaAdatbázis hiba: Nem tudom a fájlneveket kiolvasni.Alapértelmezett érték:Töröljem a lejátszólistát?Beállítás törléseTörlés...Fájl törléseFájlok törléseLeírásRészletekKönyvtár:LetiltvaLemezA lejátszott szám információinak megjelenítése a címsorbanKi&fejezésInternetes Rádióállomás szerkesztéseLejátszólista szerkesztéseSzám információk szerkesztéseSzerkesztés…Szerkesztés… Szerkesztés… F2 Zeneszám információinak szerkesztéseKódolás:Lejátszó modulHangszínszabályozóHangszínszabályozó Hangszínszabályozó:HibaHiba a másolás soránHiba a törlés soránHiba a hivatkozás létrehozásakorHiba a mozgatás soránHiba a könyvtár/kiegészítő betöltése során.&TeljesKizáró szűrő Hagyja ki azokat a fájlokat/könyvtárakat amelyre teljesül a szűrőKivéve:SzéthúzottAlbumok exportálásaElőadók exportálásaMűfaj exportálásaFő gyűjtemény exportálásaLejátszólista exportálásaSzámok exportálásaSzámok exportálása könyvtárba albumuk alapján.Számok exportálása könyvtárba előadójuk alapján.Számok exportálása könyvtárba.Számok exportálása könyvtárba műfajuk alapján.Exportálás…A(z) %s hangeszköz megnyitása sikertelen.Súlyos hibaF&ile szűrő:A fájl már létezik. Felülírjam a fájlt?A fájl nem található.A %s fájl vagy könyvtár már létezik. Fájl:FájlnévFájlnév sablonokA fájlnév változatlanFájlok:Keresés… Ctrl-F Keresőszűrő megjelenítése.Könyvtárak:Valamilyen okból kifolyólag a FOX PNG támogatás nélkül került lefordításra. Ahhoz, hogy az összes ikon megjeleníthető legyen, szükség van a PNG támogatásra. Ha a FOX könyvtárat Ön fordította, ellenőrizze, hogy a libpng fejlesztői fájlok telepítve legyenek a FOX lefordításakor.Szünetmentes lejátszásMűfajNagy képekGoggles Music Manager nem tudta megnyitni az adatbázist. Az adatbázis fájl megsérülhetett. Kérem, törölje a "~/.goggles/goggles.db" fájlt és próbálja újból. Ha a hiba továbbra is elfordul, kérem, tegyen hibabejelentést a http://code.google.com/p/gogglesmm címen.CsoportRejtett fájlokAktuális Aktuális menüpont színeSaját könyvtárSzín:Ikonokkisbetű/NagybetűNévelők figylemen kívül hagyásaKönyvtár importálása… Ctrl-O Zenék importálása a megadott könyvtárból a gyűjteménybeZenék importálásaLejátszólista exportálásaLejátszólista importálása… Létező lejátszólista importálásaÚj számok importálása Importálja azon fájlokat, amelyek eddig nem szerepeltek a gyűjteményben.Fájlok importálása…Importálás…Információk… Gyűjtemény statisztikaInternet RádióRossz sablonLejátszólisták megtartásaNagy ikonokLast.FM hiba.Last.fmGyűjtemény hibaHivatkozásHivatkozásA fájl hivatkozása innen: %s ide:Hivatkozás...CímHely:KisbetűsKisbetűs kiterjesztésMagenta:KéziKözepes képekMenü Menü színeMódosítás dátumaMódosult a legutóbbi importálás óta Csak a címkék (Tag) újraolvasása azoknál a fájloknál, amelyek a legutóbbi import óta módosultak.Lefelé mozgatFájl mozgatásaFelfelé mozgatA fájl mozgatása innen: %s ide:Mozgatás...Zenei gyűjteményZenei Gyűjtemény információkNévA hálózat nem elérhető.Új Internetes RádióállomásÚj lejátszólista… Új lejátszólista létrehozása.Új lejátszólistaÚj lejátszólista… Új lejátszólista létrehozásaÚj rádióállomás… Új rádióállomás hozzáadásaÚj Rádióállomás… Új számok:Új könyvtár...KövetkezőKövetkező A következő szám lejátszása A következő szám lejátszásaKövetkező számKövetkező szám Ctrl-] A következő szám lejátszása.Nincs változásNem változott egyetlen szám sem. Továbbra is szeretné a címkék frissítését a kijelölt számokra?No.NormálNormál Normál betűszínNormál méretű képekKikapcsolHúha! Adatbázis hiba!Beállítások:Felülírjam a fájt?Beállítás felülírása&ElőzőBeállítások beolvasásaBeállítások beolvasása innen:Jelszó:SzünetSzünet A lejátszás megakasztása A lejátszás megakasztásaSzünetSzünetLejátszásLejátszás Ctrl-P Lejátszás megkezdéseLejátszás A lejátszás elindítása A lejátszás elindításaLejátszásLejátszási hibaLejátszó gombokLejátszott Az éppen lejátszott szám színeAdja meg a beállítás nevét:Kérem adja meg a lejátszandó file-t, vagy címet:Kérem várjon. Ez eltarthat egy ideig.ElőerősítésBeállításokBeállítások…A(z) "%s" beállítás már létezik. Felülírjam?Beállítás neveBeállítás:Előnézeti képekElőzőElőző Az előző szám lejátszása Az előző szám lejátszásaElőző számElőző szám Ctrl-[ Előző szám lejátszásaSorKilépésCserélje &mindetOlvasási hibaCsak olvashatóOk.Törlés TörlésTöröljem az albumot?Mindet töröl Az összes zeneszám eltávolítása a gyűjteményből.Töröljem az előadót?A hangfájlok eltávolítása...Töröljem a hangfájlokat?Eltávolítsam a műfajt?Eltávolítsam az Internetes Rádióállomás(oka)t a gyűjteményből?Eltávolítsam az Internetes Rádióállomás(oka)t?Lejátszólista eltávolításaTöröljem a számo(ka)tEltávolítsuk az összes számot a gyűjteményből?Töröljem a számo(ka)t a gyűjteményből?Eltávolítsuk a számokat a lejátszólistából?A könyvtárban található számok eltávolítása a gyűjteménybőlTöröljem az albumhoz tartozó összes számot a gyűjteményből?Eltávolítsuk az albumhoz tartozó számokat a lejátszólistából?Töröljem az előadó összes számát a gyűjteményből?Eltávolítsuk az előadóhoz tartozó számokat a lejátszólistából?Számok törlése a lemezrőlSzámok eltávolítása a lejátszólistábólSzámok eltávolítása a gyűjteményből, melyek már nem találhatók a lemezenEltávolítsam az adott műfajú zenéket a gyűjteményből?Eltávolítsuk az ilyen műfajú számokat a lejátszólistából?Törlés… Del A műfaj eltávolítása a gyűjteményből.Törlés… Del A kijelölt számok eltávolítása a gyűjteményből.Törlés… Del A szám(ok) eltávolítása a gyűjteményből.Törlés… Del A szám eltávolítása a lejátszólistából.Átnevezzem a hangfájlokat?Hangfájlok átnevezése…Szám egy részének megjelöléseSzám egy részének ismétléseSzám egy részének ismétlése Ctrl-T A szám egy részének ismétléseÖsszes ismétlése Ctrl-/ Az összes számot ismétli.Ismétlés kikapcsolása Ctrl-, Nem ismétli a számokat.Szám ismétlése Ctrl-. Az aktuális szám ismétlése.Csere e&rre:Szóközök kicserélése alsóvonalraAlsóvonalakat cserélje szóközreLejátszás vezérlésAz erőforrás nem elérhető. Ellenőrizze a jogosultságokat.VisszafeléSorokKeresse e&ztMintavételezésTelítettség:Biztonsági figyelmeztetésFájl kiválasztásaNormál betűtípus kiválasztásaMindet kijelölKijelölt Kijelölt szöveg színeA session busz nem elérhető. A dbus-t igénylő funkciókat kikapcsoltam.A session busz nem elérhető. A dbus-t igénylő funkciókat kikapcsoltam.Könyvjelző létrehozásaExportálási sablon…A szám sorszáma a beolvasás sorrendje szerintSleep időzítő beállításaÁrnyék Árnyék színe&Műfajok megjelenítése Ctrl-G Műfajböngésző megjelenítése.Források megjelenítése Ctrl-S Forrás böngésző megjelenítése.Böngésző megjelenítéseTeljes képernyő F12 Teljes képernyő ki/bekapcsolása.Ikonok a zeneszám böngészőbenGombfeliratok megjelenítéseÁllapotsor megjelenítéseSzámváltás üzenetpanel Üzenetet küld a notification daemonnak,hogy más számot játszik már a program.Tálca ikon használata Mutassa a kis tálca ikont.Mutassa az albumborítót a szám lejátszásakor Mutassa a lejátszott szám ablumborítóját.Albumborítók megjelenítése az albumböngészőben Albumborítók megjelenítése az albumböngészőbenKeverés Ctrl-RVéletlenszerűen Alt-R A számok véletlenszerű lejátszása.MéretMin&dent kihagySleep időzítőSleep funkció Sleep funkció beállításaKapcsoljon ki Kis ikonokRendezési beállításokRendezésRendezés az album (kiadási) éve alapjánRendezésForrások Nyomja meg a sorrend megváltoztatásához Nyomja meg a sorrend megváltoztatásáhozAdja meg az új lejátszólista nevétAdja meg az új rádióállomás címét és leírásátLejátszásLejátszás.RádióállomásÁlljÁllj Ctrl-\ A lejátszás megállításaÁllj A lejátszás leállítása A lejátszás leállításaLejátszás megállítása ennyi idő utánStílusSzinkronizálás… A könyvtár szinkronizálása a gyűjteménnyelSzinkronizálásKönyvtár szinkronizálásaTálcaCímkeA sablon tartalmazhat relatív, vagy abszolút útvonalat, környezeti változót és ~ jelet. A relatív útvonalak alpjául a fájl eredeti helye szolgál. A kiterjesztést automatikusan hozzáadja a program. A következő makrók használhatók:Sablon:A következő hangfájlokat fogom törölniA következő hangfájlok kerülnek átnevezésreA megadott sablon rossz! A szám címét %%T szükséges megadni. Kérjük javítsa ki a sablont a Beállítások ablakban.A Goggles Music Manager ezen verziója nem támogatott a Last.fm által. Frissítsen egy frissebb verziójú programra.IdőCímSúgó Súgó színeTetejéreÖsszes idő:SzámSzámok:Tálca Tálca háttér színeKapcsolja ki a lejátszó modult leállításkorKapcsolja be a lejátszó modult induláskor A gyorsabb indulás érdekében a lejátszó modul csak az első szám lejátszásakor kerül elindításra. A gyorsabb indulás érdekében a lejátszó modul csak az első szám lejátszásakor kerül elindításra.TípusA fájl másolása sikertelen: %s ide: %s Folytassam a műveletet?Nem tudom létrehozni a(z) "%s" könyvtárat A fájl törlése sikertelen: %s Folytassam a műveletet?Nem tudom inicializálni a lejátszót.Nem tudom a zeneszámot az adatbázisba írni!Nem tudtam elindítani a böngészőtA fájl hivatkozása sikertelen: %s fájlt ide: %s Folytassam a műveletet?A fájl mozgatása sikertelen: %s ide: %s Folytassam a műveletet?Nem tudom az adatbázist megnyitni.Az album eltávolítása az adatbázisból sikertelen.Az előadó eltávolítása az adatbázisból sikertelen.A műfaj eltávolítása az adatbázisból sikertelen.Nem tudom a rádióállomást eltávolítani a gyűjteményből!A zeneszám eltávolítása az adatbázisból sikertelen.A fájl átnevezése sikertelenA fájl átnevezése sikertelen: %s az új névre:%sA fájl átnevezése sikertelen: %s az új névre:%s Folytassuk a fájlok átnevezését?A szám adatainak frissítése sikertelen.Ismeretlen hibaIsmeretlen eszközIsmeretlen host.NévtelenEgy szinttel feljebbFájlnév frissítéseCímkék (Tag) frissítése a fájlbanFrissítsem a címkéket (Tag)?Meglévő számok frissítéseAdja meg a rádióállomás URL-jét és leírásátAdatbázis frissítése…FelhasználóFelhasználónév:Fényerő:NézetHangerő normalizálásaFigyelmeztetésAblakFuttatási könyvtárÉvSárga:Az Ön zenei gyűjteménye a következőkből állalt Alternatív színhát Háttér színeelő Előtér színeóra ésperc múlva.…gogglesmm-0.12.7/po/fr.mo0000644000175000001440000011074512063217121013672 0ustar sxjusersw\8'9'(V'''+''-'0(1E(5w(( (!()()/)7)>)D)V)1f)5)-).)+*J*g*z6+7+ +++, ,,3,O,"W,z,!,,,!,,, - - #-/-5- =-I-R-[-c- i- s--K-9-....'#.K.Q."W.z.. ......*../ // */7/ =/J/P/W/]/e/Fj/ // / /B/ 0(0 A0O0 ^0 l0w0~0*0-0-01C1_1 h1s1 1111 11 11 2222 "202M2 b2l2<u222222 3 33433'h3 3+3333 344#4)4184j4y4 4 4 44 44 444"4 55 85F5]5 e5"o5 55 5 5 555556"696C@666 66 666 6263&7'Z727 7)7 7 74888%H8n8t8}8%88"88899 ::: : ;;.;3; 9;E;=Z; ;8;;";<#<4< D< P<^< f<t< y<+<<< < <<<< <= =O+= {= ==+== ====>)*> T>&a>+>> >>>%> ?&? ??WJ???? ????@ @@,@ =@G@M@h@x@}@"@@@@@A#A>A FARA9aA AAAA1AA& B0B6B ;B HB SB]BdB tB5BBBB B.B!.CPC`C)qCCC+C&D(,D'UD)}DD D.D&E(6E(_E4E+E-EF+FCF LF*WF+F'F)FGG/G OG*\GGG G G GGG GGJHDOH HH%HHH'I),I VI,cII IILI1JCGJEJJ/JK K K+KJK SK _KlKtKKCK K*KL/L7L~^~|~ ~ ~2~>~<&8c)) 1 ?HO_ o!{)ǀl_^с+/<H>Ă6ق1BYsuFi0f>Q Xe"n  ȅO*79b,ކ* 6D= ‡.Ƈ/..]r_f"l!ӊE'4A\)4Ȍ+C)Jm'354J57!!F1%xŏ ԏߏ ' 1&I2p& ʐ֐  7>+E*q ґܑk&2u$ T"M<OjwW4Zo1A@7+m\$H[r* bE9?nnya=}53{IreQz\/=Xx8,#Fv|,s>}0^*2 Sa4R-s~>_0Nf% 3Cc;?S| !:VGZ YB TW:1b)t{yD@d'MYOQG'Fx.u+]PLX&o )Ag #(v`J5c U9wP/V qliJ_."%^Np[iDHp`fK6Ugq!(CI;6z~]hkdeR <8-KlBLj7tmEh Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Track&View&Window&YesA DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAre you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBookmarksBorder Border ColorBothBottomBrowseBy %sCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.ColorsColumnsCondensedConfigure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Failed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:For some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport new tracks Imports files not yet in the database.Importing Files...Information… Library StatisticsInternet RadioInvalid TemplateKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMedium imagesMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesOops. Database ErrorOptions:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseRowsS&earch for:SamplerateSaturation:Security WarningSelect Normal FontSelect allSelected Selected Text ColorSession Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.This version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTooltip Tooltip ColorTopTotal Time:TrackTracks:Turn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.Project-Id-Version: Goggles Music Manager Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: Last-Translator: Erwan Inyzant Language-Team: Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Poedit-Language: French X-Poedit-Country: FRANCE X-Language: fr_FR Ajuster le Volume Ajuste le Volume Signets Parcourir les répertoires signés. Par Nom Fermer les Filtres Fermer les Filtres Créer un nouveau répertoire Créer un nouveau répertoire. Cyan, Magenta, Jaune Aller au répertoire utilisateur Revenir au répertoire utilisateur. Aller au répertoire de travail Revenir au répertoire de travail. Remonter d'un répertoire Remonter d'un répertoire dans l'arborescence. Masquer les Fichiers Cachés Masquer les fichiers et les répertoires cachés. Teinte, Saturation, Valeur Choisir une couleur Jouer le Morceau Suivant Jouer le Morceau Suivant. Jouer le morceau Précédent Jouer le morceau précédent. Rouge, Vert, Bleu Supprimer Reset Sauver Artistes Différents Mêmes Artistes Afficher en détails Afficher une liste détaillée des répertoires. Afficher les fichiers cachés Afficher les fichiers et répertoires cachés. Afficher en icônes Afficher les répertoires avec de grosses icônes. Afficher en liste Afficher les répertoires avec de petites icônes. Démarrer la lecture Démarrer la lecture Arrêter la Lecture Arrêter la Lecture%T - titre %A - nom de l'album %P - nom de l'artiste pour l'album %p - nom de l'artiste pour la piste %y - annee %d - numéro du disque %N - numéro de la piste (2 chiffres) %n - numéro de la piste %G - genre%T - Titre %P - nom de l'artiste pour l'album %p - nom de l'artiste du morceau %A - nom de l'album %N - numéro du morceau %G - genre%s Contactez le support si l'erreur se reproduit.&A Propos...&Accepter&Alpha:&Audio&Retour en arrière&Bleu:&Parcourir Ctrl-B Affiche l'explorateur d'artistes et albums.&Annuler&Effacer les bookmarks Effacer les bookmarks.&Fermer&Colonnes Changer les Colonnes Visibles.&Configurer les Colonnes...&Contrôles&Copier Ctrl-C Copie les Morceaux Sélectionnés&Créer&Couper Ctrl-X Coupe les Morceaux Sélectionnés&Répertoire&Répertoire:&Ne pas Sauver&Modifier&Exporter&Nom du Fichier:&Fichier(s)&Général&Vert:&Aide&Page officielle&Ignorer la casse&Importer&Rejoignez GMM sur last.fm... Rejoignez le groupe Goggles Music Manager sur last.fm...&Revenir au Morceau Courant Ctrl-J Affiche le morceau - album - artiste courant.&Musique&Next&Non&OK&Coller Ctrl-V Colle le Contenu du Presse Papier&Play&Quitter&Quitter Ctrl-Q Quitter l'application.&Rouge:&Supprimer&Tout Supprimer&Renommer&Remplacer&Rapporter une erreur...&Sauver&Rechercher&Créer un signet Créer un signet pour le répertoire courant.&Inscrivez vous sur last.fm...&Passer&Trier&Trier Change le Tri.&Démarrer le minuteur&Stop&Arreter l'importation&Sync&Piste&Affichage&Fenêtre&OuiErreur DBus. Toutes les fonctions qui utilisent le bus de session sont désactivées.A&pparenceAlbumArtiste de l'AlbumPochettes d'AlbumsAlbums Cliquez pour changer l'ordre de tri Cliquez pour changer l'ordre de triAlbums:Tout Toujours lire les tagsTous les %d AlbumsTous les %d ArtistesTous les %d GenresTous les GenresAlpha:Existe DéjàEtes vous sûr de vouloir supprimer le preset %s?Etes vous sûr de vouloir supprimer ce fichier ? : %sEtes vous sûr de vouloir supprimer la playlist ?ArtisteArtistes Cliquez pour changer l'ordre de tri Cliquez pour changer l'ordre de triArtistes:AttributsErreur sur le Périphérique AudioDriver Audio:Sorties Audio indisponibles.Récupération auto des N° de pistes. Offset:Base Couleur de BaseGrandes icônesBitrateBookmarkBordure Couleur de la BordureLes deuxBasExplorerPar %sImpossible à CréerImpossible de créer le répertoire %s. Modifier le nom de la playlisteModifier...CannauxChoisissez l'ordre d'apparition des informations dans le track-list.Effacer la Bibliothèque ?Effacer les bookmarksLibérer l'audio à la pause.CouleursColonnesCondenséConfigurer les ColonnesConnection Refusée.Copier Ctrl-C Copier les morceaux associés dans le presse papier.Copier Ctrl-C Copier le(s) morceau(x) dans le presse papier.Copie un FichierCopie du fichier depuis: %s vers :Copier...Créer un Nouveau RépertoireCréer une PlaylisteCréer un nouveau répertoire avec le nom :CourantPersonnaliséCyan:Erreur de base de donnéeErreur de la Base de Données : Impossible de récupérer tous les noms de fichiers.Valeur par défaut:Supprimer la Playliste ?Supprimer le PresetSupprimer...Suppression du fichierSuppression des fichiersDescriptionDétailsRépertoire:DésactiverDisqueAffiche le morceau courant dans la barre de titreE&xpressionModifier la Radio InternetModifier la PlaylisteModifier les Informations de la PisteModifier...Modifier... Editer... F2 Editer les Informations sur le morceau.Encodage:MoteurEqualiserEqualiser Equaliser:ErreurErreur en Copiant le FichierErreur à la suppression du fichierErreur en Liant le FichierErreur en Déplaçant le FichierErreur pendant le chargement de la librairie/pluginEx&actFiltre d'exclusion Permet de filtrer les répertoires et/ou les fichiers à partir d'un modèleExclure:EtenduExporter les AlbumsExporter les ArtistesExporter les GenresExporter la Bibliothèque PrincipaleExporter la Play ListeExporter les morceauxExporter les morceaux de cet album vers le répertoire de destination.Exporter les morceaux de cet artiste vers le répertoire de destination.Exporter les morceaux vers le répertoire de destination.Exporter les morceaux de ce genre dans le répertoire de destination.Exporter...Impossible d'utiliser le driver audio:%sErreur FataleF&iltre de fichier:Le fichier existe déjà. Voulez vous l'écraser ?Fichier introuvable.Le fichier ou le répertoire %s existe déjà. Fichier:Nom du FichierModèle du Nom de FichierLe nom des fichiers n'ont eu besoin d'aucuns changementsFichiers:Chercher... Ctrl-F Afficher les filtres de recherche.Dossiers:Pour une raison inconnue la librairie FOX n'a pas été compilé avec le support de PNG. Afin de permettre à Goggles Music Manager d'afficher de petites icônes, la librairie FOX doit supporter PNG. Si vous avez compilé FOX par vous-même, le header libpng ne devait pas être installé sur votre système.Lecture GaplessGenreGrandes ImagesGoggles Music Manager n'a pas réussi à ouvrir la base de donnée. La base de donnée est peut être corrompue. Supprimez ~/.goggles/goggles.db puis essayez à nouveau. Si l'erreur subsiste, vous pouvez poster un bug sur le site : http://code.google.com/p/gogglesmmGroupeFichiers cachésSurbillance Couleur de SurbrillanceRépertoire HomeTeinte:IcônesIgnorer la casseIgnorer les motsImporter... Ctrl-O Importer de la musique dans la BibliothèqueImporter la MusiqueImporter de nouveaux morceaux Importe les fichiers qui ne sont pas encore dans la base de données.Importation des Fichiers...Information... Statistiques sur la BibliothèqueRadio InternetModèle InvalideGarder les playlistesGrande IcônesErreur Last.FMLast.fmErreur sur la BibliothèqueLienLier le FichierCréer un lien depuis: %s vers :Lier...CheminPosition:MinusculeExtension minusculeMagenta:ManuelImages MoyennesMenu Couleur de Texte du MenuDate modifiéeModifiés depuis l'import Relit les tags seulement si le fichier a été modifié.Vers le BasDéplacer le FichierVers le HautDéplacer le fichier depuis: %s vers:Déplacer...BibliothèqueInformation sur la BibliothèqueNomRéseau introuvable.Nouvelle Radio InternetNouvelle Playliste... Créer une nouvelle playliste.Nouvelle PlaylisteNouvelle Playliste... Créer une nouvelle playlisteNouvelle Station Radio... Créer une nouvelle playlisteNouvelle Station... Nouvelles Pistes:Nouveau Répertoire...SuivantNext Jouer la Piste Suivante Jouer la piste suivante.Next TrackMorceau Suivant Ctrl-] Jouer le morceau suivant.Aucuns changementsAucun morceau n'a été mis à jour. Voulez vous toujours écrire les tags pour les morceaux sélectionnés?No.NormalNormal Couleur Normale du TexteImages NormalesOups. Erreur de Base de donnéeOptions:Ecraser ce fichier ?Ecraser le presetP&reviousParamètres d'analyseAnalyser les infos depuis:Mot de passe:PausePause Pause Pause dans la lectureMettre en Pause.PlayPlay Ctrl-P Démarre la lecture.Play Démarrer la Lecture Démarre la LecturePlaybackErreur de LectureContrôles du LecteurLecture Couleur de la piste actuellement en lectureEntrez le nom du preset:Veuillez attendre. Cela peut prendre un peu de temps.Pré-ampPréférencesPréférences...Le preset %s existe déjà. Voules vous l'écraser ?Nom du PresetPresets:Aperçu d'imagesPrécédentPrevious Jouer la Piste Précédente Jouer la piste précédente.Previous TrackMorceau Précédent Ctrl-[ Jouer le morceau précédent.QueueQuitterTout Rem&placerErreur de LectureLecture SeulePrêts.Supprimer Supprimer.Supprimer l'Album?Supprimer Toutes les Pistes Supprimer toutes les pistes de la bibliothèqueSupprimer l'Artiste?Supprimer les Fichiers Audio...Supprimer les Fichiers Audio ?Supprimer le Genre ?Supprimer la/les Radio(s) Internet de la Bibliothèque ?Supprimer la/les Radio(s) Internet ?Supprimer la PlaylisteSupprimer le(s) les Morceaux ?Supprimer tous les morceaux de la bibliothèque?Supprimer le(s) morceau(x) de la bibliothèque?Supprimer le(s) morceau(x) de la playliste?Supprimer de la base de données les morceaux trouvés dans les dossiersSupprimer les morceaux de l'album de la bibliothèque?Supprimer les morceaux de l'album de la playliste ?Supprimer les morceaux de cet artiste de la bibliothèque?Supprimer les morceaux de l'artiste de la playliste?Supprimer les morceaux du disqueSupprimer les morceaux de la bibliothèqueEnlever les morceaux qui ont été supprimé du disqueSupprimer tous les morceaux de ce genre de la bibliothèque?Supprimer tous les morceaux de ce genre de la bibliothèque ?Supprimer... Suppr Supprimer le Genre de la Bibliothèque.Supprimer... Suppr Supprimer les morceaux associés de la bibliothèque.Supprimer... Suppr Supprimer le(s) morceau(x) de la bibliothèque.Supprimer... Suppr Supprimer le(s) morceau(x) de la playliste.Renommer les Fichiers Audio ?Renommage des Fichiers Audio...Répeter ARépeter A-BRépeter A-B Ctrl-T Répete la section du morceau.Répéter Tous les Morceaux Ctrl-/ Répète tous les morceaux.Ne pas Répéter Ctrl-, Ne pas répéter le morceau courant.Répéter le morceau Ctrl-. Répète le morceau courant.Remplacer &par:Remplacer les espaces par des underscoresRemplacer les underscores par des espacesReplay Gain:Ressource inaccessible. Vérifiez les permissionsInverserLignesRe&cherche sur:EchantillonnageSaturation:Attention Problème de SécuritéSelection de la PoliceTout sélectionnerSélection Couleur du Texte SélectionnéLe bus de session est indisponible. Toutes les fonctions qui utilisent le bus de session sont désactivées.Le bus de session est indisponible. Toutes les fonctions qui utilisent dbus sont désactivées.Créer un bookmarkGérer le modèle d'export...Numéro des pistes selon l'ordre d'analyse.Régler le minuteurOmbre Couleur de l'OmbreAfficher les &Genres Ctrl-G Afficher l'explorateur de genre.Afficher les &Sources Ctrl-S Afficher l'explorateur de sourcesAfficher l'ExploreurPasser en Plein Ecran F12 Passer en mode plein écran.Afficher les Icônes dans l'Explorateur de PistesAfficher les LibellésAfficher la Barre de StatutAfficher les notifications de changement de morceau Informer le démon de notification des changements de morceaux.Afficher le Tray Icône Afficher le tray icône dans le système tray.Afficher la pochette d'album pour le morceau courant Afficher la pochette d'album pour le morceau courantAfficher les pochettes d'ablums dans l'explorateur Afficher les pochettes dl'ablums dans l'explorateurMélanger Ctrl-RMode Shuffle Alt-R Joue les morceaux dans un ordre aléatoire.Taille&Tout passerMinuteurMinuteur Paramétrer le minuteur.Eteindre dansPetites icônesOptions de TriTrier parTrier par année d'albumTrierSources Cliquez pour changer l'ordre de tri Cliquez pour changer l'ordre de triSpécifiez le nom de la nouvelle playlisteSpécifiez l'url et la description de la nouvelle stationDémarre la lecture.StationStopStop Ctrl\ Arrêter la lecture.Stop Arrêter la Lecture Arrêter la lectureArrête la lecture après un laps de tempsStyle:Synchroniser... Synchroniser les répertoires avec la BibliothèqueOpération de SynchroSynchroniser les répertoiresSystem TrayTagPour les Modèles vous pouvez utiliser des chemins relatifs ou absolus, des variables d'environnements et le caractère ~. Les chemins relatifs sont calculés par rapport à l'emplacement du fichier original. L'extension est récupérée automatiquement. Les macros suivantes peuvent être utilisées:Modèle:Les fichiers audio suivant vont être supprimerLes fichier audio suivant vont être renommésLe Modèle utilisé est invalide. Le titre du morceau %%T doit être spécifié. Modifiez le modèle du nom de fichier dans les préférences.Cette version de Goggles Music Manager ne gère pas Last-FM. Vous devez installer un version plus récente de GMM.DuréeTitreInfo Bulle Couleur de l'Info BulleHautDurée Totale:PistePistes:Eteindre le moteur audio à stop.Lancer le moteur Audio au démarrage. Afin que le démarrage soit plus rapide, le moteur audio est généralement lancé à la lecture de la première piste. Afin que le démarrage soit plus rapide, le moteur audio est généralement lancé à la lecture de la première piste.TypeImpossible de copier le fichier: %s vers %s Continuer l'opération?Impossible de créer le répertoire %s Impossible de supprimer le ficher : %s Continuer l'opération ?Impossible d'initialiser le driver audio.Impossible d'ajouter la piste à la base de donnéesImpossible de lancer le navigateur internetImpossible de lier le fichier: %s à: %s Continuer l'opération ?Impossible de déplacer le fichier: %s vers: %s Continuer l'opération ?Impossible d'ouvrir la base de donnéesImpossible de supprimer l'album de la bibliothèqueImpossible de supprimer l'artiste de la bibliothèqueImpossible de supprimer le genre de la bibliothèqueImpossible de Supprimer la Radio de la Bibliothèque.Impossible de supprimer le morceau de la bibliothèque.Impossible de renommer le fichierImpossible de renommer: %s en:%sImpossible de renommer: %s en:%s Continuer à renommer les fichiers ?Impossible de mettre à jour la pisteErreur InconnuePériphérique inconnuHôte inconnu.Sans-TitreRemonterMettre à jour le Nom du FichierMettre à Jour les Tags dans le FichierMise à Jour des Tags? Mettre à jour les morceaux existant :Mettre à jour l'url et la description de la radioMise à Jour de la Base de Données...UtilisateurNom d'Utilisateur:Valeur:VueNormalisation du VolumeAttentionFenêtreRépertoire de travailAnnéeJaune:Votre collection de musique s'élève à...alt bg Couleur Alternative d'Arrière Planbg Couleur d'arrière planfg Couleur de premier planHeures etminutes.gogglesmm-0.12.7/po/es.po0000644000175000001440000022162511524673460013712 0ustar sxjusers# Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the PACKAGE package. # # Víctor Pérez Masegosa 2009. # Víctor Pérez Masegosa , 2011. msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.x\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2011-01-23 13:33+0100\n" "Last-Translator: Víctor Pérez Masegosa \n" "Language-Team: Spanish\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 1.1\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Cerrar" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Configurar columnas" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Aceptar" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Cancelar" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Elije en qué orden aparecerá la información\n" "en la lista de reproducción." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Mover arriba" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Mover abajo" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Plantilla inválida" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" "La plantilla dada es inválida. El título de la pista %%T necesita ser " "especificado.\n" "Por favor, arregle el nombre de la plantilla en el panel de preferencias." #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Error de base de datos" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Oops. Error de base de datos" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Sin cambios" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Los nombres de los archivos no requirieron cambios" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "¿Renombrar archivos de audio?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Renombrando archivos de audio..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "Los siguientes archivos de audio van a ser renombrados." #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "&Renombrar" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "No se pudo renombrar el archivo" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "No se pudo renombrar el archivo:\n" "%s\n" "\n" "a:%s\n" "¿Continuar renombrando archivos?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "No se pudo renombrar el archivo:\n" "%s\n" "\n" "a:%s" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Plantilla de nombres de archivo" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "La plantilla puede contener rutas relativas o absolutas, variables de " "entorno\n" "y ~. Las rutas relativas están basadas en la localización del archivo " "original. La\n" "extensión del archivo queda automáticamente añadida. Las siguientes macros\n" "pueden ser usadas:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - título %A - nombre del album\n" "%P - nombre del artista del album %p - nombre del artista de la pista\n" "%y - año %d - número del disco\n" "%N - número de pista (2 dígitos) %n - número de pista \n" "%G - género" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "También pueden ser usadas condiciones:" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" "?c - mostrar a si c no está vacío. Si no, mostrar b.\n" "?c - mostrar c si no está vacío\n" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Plantilla:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Encodificado:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Excluir:" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Opciones:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Reemplazar espacios por guiones bajos" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Minúscula" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Extensión en minúscula" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "No." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Cola" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Título" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Artista" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Artista del álbum" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Álbum" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Disco" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Género" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Año" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Duración" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Eliminar...\tSupr\tEliminar género de la biblioteca." #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Copiar\tCtrl-C\tCopiar pistas asociadas al portapapeles." #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Eliminar...\tDel\tEliminar pistas asociadas de la biblioteca." #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Editar...\tF2\tEditar información de la pista." #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Copiar\tCtrl-C\tCopiar pista(s) al portapapeles." #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "Abrir ubicación de la carpeta\t\tAbrir ubicación de la carpeta." #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Eliminar…\tSupr\tEliminar pista(s) de la biblioteca." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Nueva lista de reproducción...\t\tCrear nueva lista de reproducción." #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Exportar..." #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Información...\t\tEstadísticas de la biblioteca" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "" "Eliminar todas las pistas\t\tEliminar todas las pistas de la biblioteca" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Editar la información de la pista" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Guardar" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Propiedades" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Nombre de archivo" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Tipo" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Tamaño" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Tasa de bits" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Tasa de muestreo" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Canales" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Pista" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tSeparar artistas" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tArtistas compartidos" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Número de pista automático. Compensación:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Actualizar etiquetas en el archivo" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Actualizar el nombre del archivo" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Ajustar plantilla de exportación..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "¿Actualizar etiquetas?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Ninguna pista fue actualizada.\n" "¿Sigues queriendo escribir las etiquetas para las pistas seleccionadas?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "¿Suprimir archivos de audio?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Eliminar archivos de audio..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Los siguientes archivos de audio serán eliminados" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Eliminar" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Exportar biblioteca principal" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Exportar lista de reproducción" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "¿Sobrescribir archivo?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "El archivo ya existe. ¿Quieres sobrescribirlo?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Exportar género" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Exportar pistas con género al directorio de destino." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Exportar artistas" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Exportar pistas del artista al directorio de destino." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Exportar álbumes" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Exportar pistas del álbum al directorio de destino." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Exportar pistas" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Exportar pistas al directorio de destino." #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Exportar" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "¿Eliminar género?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "¿Eliminar pistas con género de la biblioteca?" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "¿Eliminar artista?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "¿Eliminar pistas del artista de la biblioteca?" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "¿Eliminar álbum?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "¿Eliminar pistas del álbum de la biblioteca?" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "¿Eliminar pista(s)?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "¿Eliminar pista(s) de la biblioteca?" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Eliminar pistas del disco" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Error de biblioteca" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "No se pudo eliminar género de la biblioteca" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "No se pudo eliminar artista de la biblioteca" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "No se pudo eliminar álbum de la biblioteca" #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "No se pudo eliminar la pista de la biblioteca" #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Crear lista de reproducción" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Especificar nombre de la nueva lista de reproducción" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Crear" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Nombre" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Nueva lista de reproducción" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "¿Limpiar biblioteca de música?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "¿Eliminar todas las pistas de la biblioteca de música?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Eliminar todo" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Conservar listas de reproducción" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Información de la biblioteca de música" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Tu colección de música consiste en..." #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Pistas:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Artistas:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Álbumes:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Tiempo total:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Ecualizador" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Ecualizador:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tGuardar" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tReiniciar" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tEliminar" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Preamplificador" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Desactivado" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Manual" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Eliminar predefinición" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "¿Estás seguro de que quieres eliminar la predefinición %s?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Nombre de predefinición" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Por favor, introduce el nombre de la predefinición:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Sobreescribir predefiniciónd" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "La predefinición %s ya existe. ¿Quieres sobrescribirla?" #: src/GMFontDialog.cpp:209 #, fuzzy msgid "Ultra Condensed" msgstr "Ultra colapsado" #: src/GMFontDialog.cpp:210 #, fuzzy msgid "Extra Condensed" msgstr "Extra colapsado" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Colapsado" #: src/GMFontDialog.cpp:212 #, fuzzy msgid "Semi Condensed" msgstr "Medio colapsado" #: src/GMFontDialog.cpp:214 #, fuzzy msgid "Semi Expanded" msgstr "Medio expandido" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Expandido" #: src/GMFontDialog.cpp:216 #, fuzzy msgid "Extra Expanded" msgstr "Extra expandido" #: src/GMFontDialog.cpp:217 #, fuzzy msgid "Ultra Expanded" msgstr "Ultra expandido" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "Delgada" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 msgid "Extra Light" msgstr "Extra ligera" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 msgid "Light" msgstr "Ligera" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 msgid "Medium" msgstr "Media" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 msgid "Demibold" msgstr "Cuasi negrita" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "Negrita" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 msgid "Extra Bold" msgstr "Extra negrita" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 msgid "Heavy" msgstr "Pesada" #: src/GMFontDialog.cpp:239 #, fuzzy msgid "Reverse Oblique" msgstr "Oblicua revertida" #: src/GMFontDialog.cpp:240 #, fuzzy msgid "Reverse Italic" msgstr "Italizada revertida" #: src/GMFontDialog.cpp:242 #, fuzzy msgid "Italic" msgstr "italizada" #: src/GMFontDialog.cpp:243 #, fuzzy msgid "Oblique" msgstr "oblicua" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normal" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "&Directorio:" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&Nombre de Archivo:" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "F&iltro de Archivos:" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Solo Lectura" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Directorio:" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "&Crear marcador\t\tAñadir el directorio actual a marcadores." #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "&Limpiar marcadores\t\tLimpiar Marcadores." #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tSubir un directorio\tSubir al directorio superior." #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tIr al directorio de usuario\tVolver al directorio de usuario." #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tIr al directorio de trabajo\tVolver al directorio de trabajo." #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tMarcadores\tVisitar directorios con marcadores." #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tCrear nuevo directorio\tCrear nuevo directorio." #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tMostrar lista\tMostrar directorio con iconos pequeños." #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tMostrar iconos\tMostrar directorio con iconos grandes." #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tMostrar detalles\tMostrar listado de directorio detallado." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "\tMostrar archivos ocultos\tMostrar archivos y directorios ocultos." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "\tOcultar Archivos Ocultos\tOcultar archivos y directorios ocultos." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Sincronizar carpeta" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "Importar lista de reproducción" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Importar música" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Archivo(s)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Directorio" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "Excluir filtro\tFiltrar directorios y/o archivos basados en el patrón" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Carpetas:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Archivos:" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Sincronizar" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Sincronizar operación" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" "Importar nuevas pistas\tImporta archivos que no están en la base de datos " "todavía." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Eliminar pistas que hayan sido eliminadas del disco" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Actualizar pistas existentes:" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" "Modificado desde la última importación\t Solamente releer la etiqueta cuando " "el archivo ha sido modificado." #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Todas\tSiempre leer las etiquetas" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Eliminar pistas encontradas en la carpeta de la base de datos" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Pista" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Analizar configuración" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Analizar información de:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Etiquetar" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Ambos:" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Valor por defecto:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Establecer número de pista en base a el orden de exploración." #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - título %A - nombre del album\n" "%P - nombre del artista del album %p - nombre del artista de la pista \n" "%N - nombre de la pista %G - género" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Reemplazar guiones bajos con espacios" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Importar" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "No se pudo inicializar el controlador de audio" #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Servidor desconocido." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Dispositivo desconocido" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Red no alcanzable." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Salida de audio no disponible." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Conexión rechazada." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Archivo no encontrado." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Recurso no disponible. Comprobar permisos" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Error de lectura" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Error al cargar la librería/complemento" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Advertencia" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Aviso de seguridad" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Error desconocido" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Error" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "No se pudo crear el directorio %s.\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Por alguna razón, la librería FOX fue compilada sin soporte para PNG.\n" "Para poder ver todos los iconos, Goggles Music Manager necesita soporte\n" "para PNG en la librería FOX. Si has compilado FOX por ti mismo, lo más\n" "probable es que encabezados de libpng no fueran instalados en tu sistema." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "" "Sesión bus no disponible. Todas las características que requieren dbus están " "desactivadas." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "" "Ha ocurrido un error en DBus. Todas las características que requieren dbus " "están desactivadas." #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "" "Sesión DBus no disponible. Todas las características que requieren " "sessionbus están desactivadas." #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Error del dispositivo de audio" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Error de Last.FM" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Error de reproducción" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" "%s\n" "%s (%d)" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Eliminar…\tSupr\tEliminar pistas(s) de la lista de reproducción." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Editar..." #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "Importar..." #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Eliminar lista de reproducción" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "¿Eliminar pistas con género de la lista de reproducción?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "¿Eliminar pistas del artista de la lista de reproducción?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "¿Eliminar pistas del álbum de la lista de reproducción?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "¿Eliminar pista(s) de la lista de reproducción?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Eliminar pistas de la biblioteca de música" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Editar lista de reprodución" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Cambiar el nombre de la lista de reproducción" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "¿Eliminar lista de reproducción?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "¿Estás seguro de que quieres eliminar la lista de reproducción?" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Sí" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&No" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Preferencias" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&General" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Opciones de clasificación" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Ignorar las primeras palabras" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Carátulas" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" "Mostrar carátula de la pista en reproducción\tMostrar carátula de la pista " "en reproducción" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" "Mostrar las carátulas en el navegador de carátulas\tMostrar las carátulas en " "el navegador de carátulas" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "Bandeja del sistema" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Mostrar icono de bandeja\tMostrar icono en la bandeja de sistema." #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" "Informar sobre los cambios de pista\tInformar al demonio de notificaciones " "sobre cambios de pista." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "Esta versión de Goggles Music Manager no\n" "está soportada por Last-FM. Por favor,\n" "actualiza tu versión de GMM." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "Servicio:" #: src/GMPreferencesDialog.cpp:338 msgid "&Sign up…" msgstr "&Regístrate..." #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Nombre de usuario:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Contraseña:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "Scrobble" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Ventana" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Ventana" #: src/GMPreferencesDialog.cpp:365 #, fuzzy msgid "Close button minimizes to tray" msgstr "Botón de cerrar esconde la ventana principal" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Mostrar barra de estado" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Mostrar iconos en el navegador de pistas" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Mostrar la pista en reproducción en la barra de título" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Controles del reproductor" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Ubicación:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Arriba" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Abajo" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "Formato de título:" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Estilo:" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Mostrar etiquetas" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Iconos grandes" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "A&pariencia" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Colores" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "fg\tColor del primer plano" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "bg\tColor de fondo" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt bg\tColor de fondo alternativo" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normal\tColor de texto normal" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Base\tColor base" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Seleccionado\tColor de texto seleccionado" #: src/GMPreferencesDialog.cpp:433 #, fuzzy msgid "Menu\tMenu Base Color" msgstr "Menú\tColor de texto del menú" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menú\tColor de texto del menú" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Borde\tColor de borde" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Consejo\tColor de consejos" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Destacado\tColor del destacado" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Sombra\tColor de la sombra" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Reproduciendo\tColor de la pista en reproducción" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "Tray\tColor del fondo de la bandeja" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Predefinidos:" #: src/GMPreferencesDialog.cpp:481 #, fuzzy msgid "Font & Icons" msgstr "Fuentes & Iconos" #: src/GMPreferencesDialog.cpp:487 msgid "Default Font" msgstr "Fuente por defecto:" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Cambiar..." #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Iconos" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Audio" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Motor" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Controlador de audio:" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Cerrar el dispositivo de audio en pausa." #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Apagar el motor de reproducción en stop." #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" "Encender el motor de reproducción al inicio.\tPara una inicialización más " "rápida, el motor de reproducción normalmente se enciende cuando la primera " "pista es reproducida.\tPara una inicialización más rápida, el motor de " "reproducción normalmente se enciende cuando la primera pista es reproducida." #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Reproducción" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Ganancia de repetición:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "Apagado" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Reproducción sin espacios" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Normalización del volumen" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "No se pudo inicializar el controlador de audio: %s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Actual" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Personalizado" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "No se pudo iniciar el navegador web" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Seleccionar fuente normal" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Siguiente" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "A&nterior" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Reproducir" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Parar" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Mostrar navegador" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Salir" #: src/GMRemote.cpp:385 #, fuzzy msgid "\tShow Browser\tShow Browser" msgstr "Mostrar navegador" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tEmpezar reproducción\tEmpezar reproducción" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tParar reproducción\tParar reproducción" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tReproducir pista anterior\tReproducir pista anterior." #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tReproducir pista siguiente\tReproducir pista siguiente." #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tAjustar volumen\tAjustar volumen" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "No se pudo abrir la base de datos" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "" "Error de base de datos: No se pudieron recuperar todos los nombres de " "archivos." #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "No se pudo actualizar pista" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "No se pudo insertar la pista en la base de datos" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Error Fatal" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Por favor, contacta con soporte si este error continúa ocurriendo." #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Actualizando base de datos..." #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Por favor, espera. Esto puede tomar un tiempo." #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Nuevas Pistas:" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "Archivo:" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Importando archivos..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "&Parar importación" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "Orígenes\tPulsa para cambiar el orden\tPulsa para cambiar el orden" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Nueva lista de reproducción...\t\tCrear nueva lista de reproducción" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "" "Importar lista de reproducción...\t\tImportar lista de reproducción existente" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Nueva estación de radio...\t\tCrear nueva lista de reproducción" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Estación" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Nueva estación...\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Editar...\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Eliminar\t\tEliminar." #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Nueva estación de radio de Internet" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Especifica url y descripción de la nueva estación" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "C&rear" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "Ubicación" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "Descripción" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Sin título" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Editar estación de radio de Internet" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Actualizar la url y descripción de la estación" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "¿Eliminar estación(es) de radio de Internet?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "¿Eliminar estación(es) de radio de Internet de la biblioteca?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "No se pudo eliminar la estación de la biblioteca" #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" "Una incompatible (futura) versión de la base de datos ha sido encontrada.\n" "Suele pasar cuando intentas hacer un downgrade a una versión más antigua de " "GMM\n" "Presiona OK para continuar y resetear la base de datos (¡Se perderá toda la " "información!).\n" "Presiona Cancelar para salir ahora mismo y dejar la base de datos como está." #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" "Goggles Music Manager no pudo abrir la base de datos.\n" "La base de datos puede haberse corrompido. Por favor, elimina ~/.goggles/" "goggles.db y prueba de nuevo.\n" "Si el error sigue ocurriendo, por favor, avísanos del problema en http://" "code.google.com/p/gogglesmm" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tCerrar Filtro\tCerrar Filtro" #: src/GMTrackView.cpp:246 #, fuzzy msgid "&Find" msgstr "Encontrar" #: src/GMTrackView.cpp:252 #, fuzzy msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "Géneros\tPulsar para cambiar el orden\tPulsar para cambiar el orden" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "Artistas\tPulsar para cambiar el orden\tPulsar para cambiar el orden" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "Álbumes\tPulsar para cambiar el orden\tPulsar para cambiar el orden" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Configurar Columnas..." #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Navegar" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Aleatorio\tCtrl-R" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Invertido" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Todos %d los géneros" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Todos los géneros" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Todos %d los artistas" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Todos %d los álbumes" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "Por %s" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Ordenar por año del álbum" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Columnas\t\tCambiar columnas visibles." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "&Orden\t\tCambiar orden." #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "Reproducir" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "Parar" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Pista anterior" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Pista posterior" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Reproducir\tEmpezar reproducción\tEmpezar reproducción" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Pausar\tPausar\tPausar reproducción" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Parar\tParar reproducción\tParar reproducción" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Previa\tReproducir pista previa\tReproducir pista previa." #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Siguiente\tReproducir siguiente pista\tReproducir siguiente pista." #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Música" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" "Importar carpeta...\tCtrl-O\tImportar música de una carpeta a la biblioteca" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "" "Sincronizar carpeta...\t\tSincronizar carpeta con música en la biblioteca" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "Reproducir medio…\t\tReproducir medio" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "&Salir\tCtrl-Q\tSalir de la aplicación." #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "&Editar" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Copiar\tCtrl-C\tCopiar las Pistas Seleccionadas" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "&Cortar\tCtrl-X\tCortar las Pistas Seleccionadas" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "&Pegar\tCtrl-V\tPegar la selección del Portapapeles" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Buscar...\tCtrl-F\tMostrar filtro de búsqueda." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Preferencias" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Ver" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "&Navegar\tCtrl-B\tMostrar navegador de género, artista y álbum." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "Mostrar &Géneros\tCtrl-G\tMostrar navegador de géneros." #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Mostrar &Fuentes\tCtrl-S\tMostrar navegador de orígenes" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Mostrar Pantalla Completa\tF12\tCambiar a modo de pantalla completa." #: src/GMWindow.cpp:296 #, fuzzy msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Mostrar Mini Reproductor\tF11\tCambiar a Mini Reproductor." #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Ordenar" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "" "&Saltar a la Pista Actual\tCtrl-J\tMostrar la pista que se está " "reproduciendo." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Control" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Reproducir\tCtrl-P\tIniciar reproducción." #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Parar\tCtrl-\\\tParar reproducción." #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Pista anterior\tCtrl-[\tReproducir pista siguiente." #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Siguiente Pista\tCtrl-]\tReproducir pista anterior." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Repetir Apagado\tCtrl-,\tRepetir pista actual." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Repetir Pista\tCtrl-.\tRepetir pista actual." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Repetir Todas las Pistas\tCtrl-/\tRepetir todas las pistas." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Repetir A-B\tCtrl-T\tRepetir sección de pista." #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Modo Aleatorio\tAlt-R\tReproducir pistas en orden aleatorio." #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Ecualizador\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Temporizador\t\tConfigurar temporizador." #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Ayuda" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Página principal" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "&Reportar Problema..." #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Regístrate en Last.fm..." #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" "&Únete a GMM en last.fm...\t\tÚnete al grupo de Goggles Music Manager en " "last.fm..." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&Acerca de..." #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "Pausar" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Anterior" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Siguiente" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "Iniciar reproducción." #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 msgid "Start playback" msgstr "Iniciar reproducción" #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Pausar reproducción." #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "Pausar reproducción" #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Repetir A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Repetir A" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "Reproducir medio" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "Por favor, especifique un archivo o url a reproducir:" #: src/GMWindow.cpp:1206 msgid "…" msgstr "..." #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "Seleccionar Archivo" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Temporizador" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Configurar temporizador" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Para la reproducción en un cierto tiempo" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Iniciar Temporizador" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Dormir en" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "horas y" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "minutos." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Biblioteca Musical" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Radio de Internet" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Salir" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Saltar" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Saltar &Todos" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&No Guardar" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tElige color" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tTono, saturación, valor" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tRojo, Verde, Azul" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Rojo:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Verde:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Azul:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Tono:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Saturación:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Valor:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tCian, Magenta, Amarillo" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Cian:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Magenta:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Amarillo:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tPor Nombre" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Crear Nuevo Directorio" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Ya Existe" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "No se pudo crear" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Copiar Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Error Copiando Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Mover Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Error Moviendo Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Enlazar Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Error Enlazando Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Borrando archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Error Borrando Archivo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Un nivel arriba" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Directorio personal" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Directorio de trabajo" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Orden" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Ignorar mayúsculas o minúsculas" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Archivos ocultos" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Marcadores" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Crear marcador" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Limpiar marcadores" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Nuevo directorio..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Copiar..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Mover..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Enlazar..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Eliminar..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Fecha Modificada" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Usuario" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Grupo" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Atributos" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Enlace" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Crear nuevo directorio con nombre:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "El archivo o directorio %s ya existe.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "No se puede crear el directorio %s.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Copiar archivo de:\n" "\n" "%s\n" "\n" "a:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "No se pudo copiar archivo:\n" "\n" "%s a: %s\n" "\n" "¿Continuar con la operación?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Mover archivo de:\n" "\n" "%s\n" "\n" "a:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "No se pudo mover archivo:\n" "\n" "%s a: %s\n" "\n" "¿Continuar con la operación?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Enlazar archivo de:\n" "\n" "%s\n" "\n" "a:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "No se pudo enlazar archivo:\n" "\n" "%s a: %s\n" "\n" "¿Continuar con la operación?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Borrando archivos" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Estás seguro de que quieres borrar el archivo:\n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "No se pudo borrar archivo:\n" "\n" "%s\n" "\n" "¿Continuar con la operación?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Seleccionar todo" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Ordenar por" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Ver" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Iconos pequeños" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Iconos grandes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Detalles" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Filas" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Columnas" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Previsualizar imágenes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Imágenes normales" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Imágenes medianas" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Imágenes gigantes" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Reemplazar" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Re&emplazar Todos" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "B&uscar:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Reemplazar &con:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "Ex&acto" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Ignorar mayúsculas y minúsculas" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "E&xpresión" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Hacia Atrás" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Búsqueda" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Listo." #~ msgid "Old Name" #~ msgstr "Nombre anteriorro" #~ msgid "New Name" #~ msgstr "Nombre nuevo" #~ msgid "Pitch:" #~ msgstr "Tono:" #~ msgid "Any" #~ msgstr "Cualquiera" #~ msgid "Fixed" #~ msgstr "Fijo" #~ msgid "Variable" #~ msgstr "Variable" #~ msgid " Type:" #~ msgstr " Tipo:" #~ msgid "Scalable" #~ msgstr "Escalable" #~ msgid "Size:" #~ msgstr "Tamaño:" #~ msgid "Family:" #~ msgstr "Familia:" #~ msgid "Always Show Remote" #~ msgstr "Siempre mostrar remoto" #~ msgid "Source\tActive Source Color" #~ msgstr "Origen\tColor del origen activo" #~ msgid "About" #~ msgstr "Acerca de" #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "&Únete a GMM en Last.fm...\tÚnete al grupo de Goggles Music Manager en " #~ "Last.fm... \tÚnete al grupo de Goggles Music Manager en Last.fm..." #~ msgid "Font" #~ msgstr "Fuente" #~ msgid "Theme Directory:" #~ msgstr "Directorio del tema:" #~ msgid "Select Theme Directory" #~ msgstr "Seleccionar directorio del tema" #~ msgid "thin" #~ msgstr "fino" #~ msgid "normal" #~ msgstr "normal" #~ msgid "bold" #~ msgstr "negrita" #~ msgid "regular" #~ msgstr "regular" #~ msgid "&Weight:" #~ msgstr "&Peso:" #~ msgid "&Style:" #~ msgstr "&Estilo:" #~ msgid "Si&ze:" #~ msgstr "Ta&maño:" #~ msgid "Character Set:" #~ msgstr "Juego de Caracteres:" #~ msgid "West European" #~ msgstr "Europeo del Oeste" #~ msgid "East European" #~ msgstr "Europeo del Este" #~ msgid "South European" #~ msgstr "Sur europeo" #~ msgid "North European" #~ msgstr "Noreuropeo" #~ msgid "Cyrillic" #~ msgstr "Cirílico" #~ msgid "Arabic" #~ msgstr "Arábigo" #~ msgid "Greek" #~ msgstr "Griego" #~ msgid "Hebrew" #~ msgstr "Hebreo" #~ msgid "Turkish" #~ msgstr "Turco" #~ msgid "Nordic" #~ msgstr "Nórdico" #~ msgid "Thai" #~ msgstr "Tailandés" #~ msgid "Baltic" #~ msgstr "Báltico" #~ msgid "Celtic" #~ msgstr "Celta" #~ msgid "Russian" #~ msgstr "Ruso" #~ msgid "Central European (cp1250)" #~ msgstr "Centro Europeo (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Ruso (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Latino1 (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Griego (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Turco (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Hebreo (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Arábigo (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Báltico (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Vietnamita (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Tailandés (cp874)" #~ msgid "UNICODE" #~ msgstr "UNICODE" #~ msgid "Set Width:" #~ msgstr "Elegir Anchura:" #~ msgid "All Fonts:" #~ msgstr "Todas las Fuentes:" #~ msgid "Preview:" #~ msgstr "Previsualización:" #, fuzzy #~ msgid "Import Playlist…\t\tImport a existing playlist" #~ msgstr "Nueva lista de reproducción...\t\tCrear nueva lista de reproducción" #~ msgid "Import Files?" #~ msgstr "¿Importar archivos?" #~ msgid "" #~ "Would you like import the pasted files and/or directories into the Music " #~ "Library?" #~ msgstr "" #~ "¿Tegustaría importar los archivos pegados y/o los directorios en la " #~ "Biblioteca de Música?" #, fuzzy #~ msgid "Now Playing" #~ msgstr "Nueva lista de reproducción" #~ msgid "Open URL…\t\tOpen Stream or File" #~ msgstr "Abrir URL...\t\tAbrir flujo o archivo" #~ msgid "Open MRL" #~ msgstr "Abrir MRL" #~ msgid "P&ause" #~ msgstr "P&ausar" #~ msgid "\tPause\tPause Playback" #~ msgstr "\tPausar\tPausar reproducción" #~ msgid "A capella" #~ msgstr "A capella" #~ msgid "Acid" #~ msgstr "Acid" #~ msgid "Acid Jazz" #~ msgstr "Acid Jazz" #~ msgid "Acid Punk" #~ msgstr "Acid Punk" #~ msgid "Acoustic" #~ msgstr "Acústica" #~ msgid "Alternative" #~ msgstr "Alternativa" #~ msgid "AlternRockAmbient" #~ msgstr "AlternRockAmbient" #~ msgid "Avantgarde" #~ msgstr "Avantgarde" #~ msgid "Ballad" #~ msgstr "Balada" #~ msgid "Bass" #~ msgstr "Bajo" #~ msgid "Bebob" #~ msgstr "Bebob" #~ msgid "Big Band" #~ msgstr "Big Band" #~ msgid "Blues" #~ msgstr "Blues" #~ msgid "Bluegrass" #~ msgstr "Bluegrass" #~ msgid "Booty Bass" #~ msgstr "Booty Bass" #~ msgid "Cabaret" #~ msgstr "Cabaret" #~ msgid "Chamber Music" #~ msgstr "Música de Cámara" #~ msgid "Chanson" #~ msgstr "Chanson" #~ msgid "Chorus" #~ msgstr "Coro" #~ msgid "Christian Rap" #~ msgstr "Rap Cristiano" #~ msgid "Classical" #~ msgstr "Clásica" #~ msgid "Classic Rock" #~ msgstr "Rock Clásico" #~ msgid "Club" #~ msgstr "Club" #~ msgid "Comedy" #~ msgstr "Comedy" #~ msgid "Country" #~ msgstr "Country" #~ msgid "Cult" #~ msgstr "Cult" #~ msgid "Dance" #~ msgstr "Dance" #~ msgid "Dance Hall" #~ msgstr "Dance Hall" #~ msgid "Darkwave" #~ msgstr "Darkwave" #~ msgid "Death Metal" #~ msgstr "Death Metal" #~ msgid "Disco" #~ msgstr "Disco" #~ msgid "Dream" #~ msgstr "Dream" #~ msgid "Drum Solo" #~ msgstr "Solo de Batería" #~ msgid "Duet" #~ msgstr "Dúo" #~ msgid "Easy Listening" #~ msgstr "Easy Listening" #~ msgid "Electronic" #~ msgstr "Electrónica" #~ msgid "Ethnic" #~ msgstr "Étnica" #~ msgid "Euro-Dance" #~ msgstr "Euro-Dance" #~ msgid "Euro-House" #~ msgstr "Euro-House" #~ msgid "Euro-Techno" #~ msgstr "Euro-Techno" #~ msgid "Fast Fusion" #~ msgstr "Fusión Rápida" #~ msgid "Folk" #~ msgstr "Folk" #~ msgid "Folk-Rock" #~ msgstr "Folk-Rock" #~ msgid "Folklore" #~ msgstr "Folclore" #~ msgid "Freestyle" #~ msgstr "Freestyle" #~ msgid "Funk" #~ msgstr "Funk" #~ msgid "Fusion" #~ msgstr "Fusión" #~ msgid "Game" #~ msgstr "Juego" #~ msgid "Gangsta" #~ msgstr "Gangsta" #~ msgid "Gospel" #~ msgstr "Gospel" #~ msgid "Gothic" #~ msgstr "Gótico" #~ msgid "Gothic Rock" #~ msgstr "Rock Gótico" #~ msgid "Grunge" #~ msgstr "Grunge" #~ msgid "Hard Rock" #~ msgstr "Hard Rock" #~ msgid "Hip-Hop" #~ msgstr "Hip-Hop" #, fuzzy #~ msgid "House" #~ msgstr "Euro-House" #, fuzzy #~ msgid "Humour" #~ msgstr "HouseHumour" #~ msgid "Industrial" #~ msgstr "Industrial" #~ msgid "Instrumental" #~ msgstr "Instrumental" #~ msgid "Instrumental Pop" #~ msgstr "Pop Instrumental" #~ msgid "Instrumental Rock" #~ msgstr "Rock Instrumental" #~ msgid "Jazz" #~ msgstr "Jazz" #~ msgid "Jazz+Funk" #~ msgstr "Jazz+Funk" #~ msgid "Jungle" #~ msgstr "Jungla" #~ msgid "Latin" #~ msgstr "Latino" #~ msgid "Lo-Fi" #~ msgstr "Lo-Fi" #~ msgid "Meditative" #~ msgstr "Meditativo" #~ msgid "Metal" #~ msgstr "Metal" #~ msgid "Musical" #~ msgstr "Musical" #~ msgid "National Folk" #~ msgstr "Folk Nacional" #~ msgid "Native American" #~ msgstr "Native American" #~ msgid "New Age" #~ msgstr "New Age" #~ msgid "New Wave" #~ msgstr "New Wave" #~ msgid "Noise" #~ msgstr "Ruido" #~ msgid "Oldies" #~ msgstr "Oldies" #~ msgid "Opera" #~ msgstr "Opera" #~ msgid "Other" #~ msgstr "Otro" #~ msgid "Polka" #~ msgstr "Polka" #~ msgid "Pop" #~ msgstr "Pop" #~ msgid "Pop-Folk" #~ msgstr "Pop-Folk" #~ msgid "Pop/Funk" #~ msgstr "Pop/Funk" #~ msgid "Porn Groove" #~ msgstr "Groove Porno" #~ msgid "Power Ballad" #~ msgstr "Power Balada" #~ msgid "Pranks" #~ msgstr "Bromas" #~ msgid "Primus" #~ msgstr "Primus" #~ msgid "Progressive Rock" #~ msgstr "Rock Progresivo" #~ msgid "Psychadelic" #~ msgstr "Psicodélico" #~ msgid "Psychedelic Rock" #~ msgstr "Rock Psicodélico" #~ msgid "Punk" #~ msgstr "Punk" #~ msgid "Punk Rock" #~ msgstr "Punk Rock" #~ msgid "R&B" #~ msgstr "R&B" #~ msgid "Rap" #~ msgstr "Rap" #~ msgid "Rave" #~ msgstr "Rave" #~ msgid "Reggae" #~ msgstr "Reggae" #~ msgid "Retro" #~ msgstr "Retro" #~ msgid "Revival" #~ msgstr "Revival" #~ msgid "Rhythmic Soul" #~ msgstr "Soul Rítmico" #~ msgid "Rock" #~ msgstr "Rock" #~ msgid "Rock & Roll" #~ msgstr "Rock & Roll" #~ msgid "Samba" #~ msgstr "Samba" #~ msgid "Satire" #~ msgstr "Sátira" #~ msgid "Showtunes" #~ msgstr "Showtunes" #~ msgid "Ska" #~ msgstr "Ska" #~ msgid "Slow Jam" #~ msgstr "Jam Lenta" #~ msgid "Slow Rock" #~ msgstr "Rock Lento" #~ msgid "Sonata" #~ msgstr "Sonata" #~ msgid "Soul" #~ msgstr "Soul" #~ msgid "Soundtrack" #~ msgstr "Banda Sonora" #~ msgid "Sound Clip" #~ msgstr "Clip de Sonido" #~ msgid "Southern Rock" #~ msgstr "Rock Sureño" #~ msgid "Space" #~ msgstr "Espacio" #~ msgid "Speech" #~ msgstr "Discurso" #~ msgid "Swing" #~ msgstr "Swing" #~ msgid "Symphonic Rock" #~ msgstr "Rock Sinfónico" #~ msgid "Symphony" #~ msgstr "Sinfonía" #~ msgid "Tango" #~ msgstr "Tango" #~ msgid "Techno" #~ msgstr "Techno" #~ msgid "Techno-Industrial" #~ msgstr "Techno-Industrial" #~ msgid "Top 40" #~ msgstr "40 Principales" #~ msgid "Trailer" #~ msgstr "Trailer" #~ msgid "Trance" #~ msgstr "Trance" #~ msgid "Tribal" #~ msgstr "Tribal" #~ msgid "Trip-Hop" #~ msgstr "Trip-Hop" #~ msgid "Vocal" #~ msgstr "Vocal" #~ msgid "Start Up:" #~ msgstr "Inicio:" #~ msgid "Show Main Window" #~ msgstr "Mostrar ventana principal" #~ msgid "Show Mini Remote" #~ msgstr "Mostrar mini-reproductor" #~ msgid "Previous View" #~ msgstr "Modo anterior" #, fuzzy #~ msgid "Configure Columns…" #~ msgstr "&Configurar Columnas..." #~ msgid "Yes" #~ msgstr "Sí" #~ msgid "Edit…\tF2\tEdit Genre." #~ msgstr "Editar…\tF2\tEditar Género." #~ msgid "Edit…\tF2\tEdit Artist." #~ msgstr "Editar...\tF2\tEditar Artista." #~ msgid "Edit…\tF2\tEdit Album." #~ msgstr "Editar…\tF2\tEditar Álbum." gogglesmm-0.12.7/po/pt.mo0000644000175000001440000011363112063217121013703 0ustar sxjusers<\ (+)+(F+o+x++++-+0,15,5g,, ,!,), --'-.-4-1O-5---.-.3.P.z/ /7/ //// /030C0"K0n0!u000!000 1 1 1#1)1 11=1F1L1U1]1 c1 m1z1K1912222'2E2 K2W2"]222 222222*22 333%3 <3I3 O3\3b3g3n3t3|3W3F3 4,4 24 ?4BL444 44 4 4444*6-06-^66C66 66 6 7&7A7 Q7[7c7 h7r777777 777 77<778L8\8y888 888848',9 T9+^9999 9999919 .:;:J: \: j: t::: :: :::": :: ; ;7; ?;"I; l;v; }; ; ;;;;;;";<C<^<g< p<~< <<< <2<3='4=2\= = === =)= = >4>H>%X>~>>>%>>">> >? @@ !@.@AA !A.ABAQAVA \AhA=}A AA,A8B>B QB"[B~BBBB B BB BBB B+B&C.C 7C ACLCaCjCqC xCCC COC D D"D+*DVD ^DlDDDD)D D&D+EGE XEdEuE%zE E&E EWE5F9F@F YFgFoFsF+FFFF FFF GGG3GBGRGWG"sGG+GGGGGH%4H#ZH~H HH9H HHHH1I:I&IIpIvI {I I III I5IIJJ 1J.?J!nJJJ)JJJ+K&EK(lK'K)KK K. L&OL(vL(L4L+L-)MWMkMM M*M+M'M)N@NONoN N*NNNNN N O OO O 1O=O PO[OxO OOJODO .P;P%RPxPP'P)P P,P*Q FQ+RQ~QLQ1QC REQRR/RR R RRS S %S2S:SMSCUS S*SSST TT ,T#MTqT8xTTT TT@T$U U1 V1;VmVVlVfWkW qWWW WWWW!WWXXX;XY4;Y"pY(YY;Y;ZPZ'lZ(Z'Z*Z([9[O[4k[[ [[ [[ [[\ \(\%@\f\{\ \\\\\\\\\#\#\]2] F]P]Y]]]^$_ >_H_,e__:_B_2)`=\`` `4`4`+aBaKaRa&Za/a8a6a8!b*Zb&bby{c c7d8d?dHdOdWd_d1fd d%dd#dd e)e?e)Fe pe |e ee ee e eeeeee fLf=dff fff4f f gg g 5g@g Ig Wg cgogg g*ggggghh&h-h Ah NhXh_hdhlh_qhDhii%i7i=Gii#iiiiij j j&k-Fk;tkk>k k l l l,l"Ll ol}l ll llllllll"l# m DmOm>Vmmmm'mmn n(n@nSnGfn<nnn o%o;o!Woyo ooo:ooo p-p BpNpbp wp pp ppp/p pp q(q Fq Pq*\qqq q q qqqqqr$-rRrAYr r rrrrrs$s.4s/cs!s/s s sst t*,t Wtbt+ktt(t ttt) u 6u,Aunuvuuvvvvw wwwwwwwxH'xpxxAxCx'y ?y,Kyxyyyyy yyyy z zz 7z DzNz ]zizzzzzzzzYz <{G{ V{`{~{ {{{{{?{#|:>|8y|| |||<|-}/<}l}]}}}}}~ ~ ~~*9~ d~n~~ ~ ~ ~~~~~~ &4EzC  , 7'U+} Ā1Ҁ #<,i/xÁ Ӂ߁=EVr-˂%?*^7!--9?y,-9,J:w,8߅2 P Z,f,&(%!%G m1zɇ܇ '<V#f LMPa*s'ȉ%8)'b >׊X>H__G/W Ȍь  <Y*v ˍՍۍ+.'VD]Ď׎>)0:|ko aks )ޑ+ !7$Y#~+"Γ7*) Tu+˔ (0>Yŕޕ (G[(x ɖՖܖ!*Ddu * 4"qLy-oA?q]|[=K YBFhwbHeJXZ@<f~>*cc A1+\-F sJMdS!%y  )7=UmuE;ranL8WQw]2x _`gn5g>C!izI#aUPO{& 4Srht3b1Y:6)/%|j_ERG MCf,sV$}(.$D2xl`^7lTdBWK'PRv@^';p~3iZH, ?.pj<X"&oNem:D5968N0 9/+V(#zkvGT{\0kQt[Iu}O Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Show Browser Show Browser Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s %s (%d)%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&Find&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Properties&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Sign up…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Tag&Track&View&Window&Yes?c - display a if c is not empty else display b. ?c - display c if not empty A DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAn incompatible (future) version of the database was found. This usually happens when you try to downgrade to a older version of GMM Press OK to continue and reset the database (all information will be lost!). Press Cancel to quit now and leave the database as is.Are you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBoldBookmarksBorder Border ColorBothBottomBrowseBy %sC&reateCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.Close button minimizes to trayColorsColumnsCondensedConditions may be used as well:Configure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default FontDefault value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDemiboldDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Extra BoldExtra CondensedExtra ExpandedExtra LightFailed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:Font & IconsFor some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHeavyHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport PlaylistImport Playlist… Import existing playlistImport new tracks Imports files not yet in the database.Importing Files...Import…Information… Library StatisticsInternet RadioInvalid TemplateItalicKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLightLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMediumMedium imagesMenu Menu Base ColorMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesObliqueOffOops. Database ErrorOpen Folder Location Open Folder Location.Options:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playbackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlay File or StreamPlay File or Stream… Play File or StreamPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please specify a file or url to play:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseReverse ItalicReverse ObliqueRowsS&earch for:SamplerateSaturation:ScrobbleSecurity WarningSelect FileSelect Normal FontSelect allSelected Selected Text ColorSemi CondensedSemi ExpandedService:Session Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Mini Player Ctrl-M Toggle Mini Player.Show Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playbackStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTags Press to change sorting order Press to change sorting orderTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.ThinThis version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTitle Format:Tooltip Tooltip ColorTopTotal Time:TrackTracks:Tray Tray Background ColorTurn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUltra CondensedUltra ExpandedUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.…Project-Id-Version: gogglesmm Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2011-11-16 22:22-0000 Last-Translator: Sérgio Marques Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Poedit-Language: Portuguese X-Poedit-Country: Portugal Ajustar volume Ajustar volume Marcadores Ver diretórios marcados Por nome Fechar filtro Fechar filtro Criar novo diretório Criar novo diretório Ciano, magenta, amarelo Ir para o diretório pessoal Ir para o diretório pessoal Ir para o diretório de trabalho Ir para o diretório de trabalho Subir um diretório Ir para o diretório superior Ocultar ficheiros Não mostrar diretórios/ficheiros ocultos Tom, saturação, valor Escolher cor Reproduzir faixa seguinte Reproduzir faixa seguinte Reproduzir faixa anterior Reproduzir faixa anterior Vermelho, verde, azul Remover Repor Gravar Mostrar explorador Mostrar explorador Mostrar detalhes Exibir detalhes do diretório Mostrar ficheiros Mostrar diretórios/ficheiros ocultos Mostrar ícones Exibir diretório com ícones grandes Mostrar em lista Exibir diretório com ícones pequenos Iniciar reprodução Iniciar reprodução Parar reprodução Parar reprodução%T - título %A - album name %P - artista do álbum %p - artista da faixa %y - ano %d - disc number %N - n.º da faixa (2 dígitos) %n - n.º da faixa %G - género%T - titulo %A - álbum %P - artista do álbum %p - artista da faixa %N - n.º da faixa %G - género%s %s (%d)%s Contacte o programador se este erro voltar a ocorrerSo&bre&Aceitar&Alfa:Á&udio&VoltarA&zul:E&xplorar Ctrl-B Mostrar género, artista e ábum&CancelarApagar mar&cadores Apagar marcadoresFe&char&Colunas Alterar colunas visíveis&Configurar colunas...&Controlo&Copiar Ctrl-C Copiar faixas selecionadasC&riarCor&tar Ctrl-X Cortar faixas selecionadas&DiretórioDire&tório:Não &gravar&Editar&ExportarNome do &ficheiro:&Ficheiro(s)&Procurar&Geral&Verde:Aju&daPa&gina inicial&Ignorar capitulares&ImportarIntegrar o gr&upo GMM da last.fm... Integração no grupo GMM da last.fm...&Ir para a faixa atual Ctrl-J Mostrar a faixa em reprodução&MúsicaSegui&nte&Não&OKC&olar Ctrl-V Colar dados da área de transferênciaRe&produzir&Propriedades&Sair&Sair Ctrl-Q Sair da aplicaçãoVe&rmelho:&Remover&Remover tudoMuda&r nomeSubstitui&r&Reportar problema...&GravarPe&squisar&Definir marcadort Marcar diretório atualIniciar &sessão na last.fm...Iniciar &sessão...I&gnorarOr&demOr&denar Alterar ordem&AtivarP&arar&Parar importação&SincronizarDe&talhesFai&xa&Ver&Janela&Sim?c - exibe "a" se "c" não for vazio, senão exibe "b". ?c - exibe "c" se não vazio Ocorreu um erro DBus. Todas as funções sessionbus estão inativas.As&petoÁlbumArtista do álbumCapas de álbumÁlbuns Prima para alterar a ordem Prima para alterar a ordemÁlbums:Sempre Reanalisar todos os detalhesTodos os %d álbunsTodos os %d artistasTodos os %d génerosTodos os génerosAlfa:Já existeFoi encontrada uma base de dados incompatível. Normalmente, esta situação ocorre ao instalar uma versão antiga do GMM Prima OK para continuar e iniciar a base de dados (as informações serão perdidas!). Prima Cancelar para sair e manter a base de dados intacta.Tem a certeza de que quer eliminar %s?Tem a certeza de que pretende eliminar: %s ?Tem a certeza de que quer eliminar a lista de reprodução?ArtistaArtistas Prima para alterar a ordem Prima para alterar a ordemArtistas:AtributosErro de dispositivoControlador:Sistema de som não disponívelN.º de faixa automático. Inicia:Base Cor baseÍcones grandesQualidadeNegritoMarcadoresContornos Cor dos contornosAmbosEm baixoExplorarPor %sC&riarIncapaz de criarIncapaz de criar o diretório %s. Mudar nome da lista de reproduçãoAlterar...CanaisEscolha a ordem das informações a exibir na lista de faixas.Apagar coleção?Apagar marcadoresFechar dispositivo ao pausarBotão "Fechar" minimiza para a bandejaCoresColunasCondensadaTambém pode utilizar estas condições:Configurar colunasLigação recusadaCopiar Ctrl-C Copiar faixas relacionadas para a área de transferênciaCopiar Ctrl-C Copiar faixa(s) para a área de transferênciaCopiar ficheiroCopiar ficheiro de: %s para: Copiar...Criar novo diretórioCriar lista de reproduçãoCriar novo diretório com o nome:AtualPersonalizarCiano:Erro na base de dadosErro na base de dados: incapaz de obter nome dos ficheirosLetra pré-definidaValor pré-definido:Eliminar lista de reprodução?Eliminar pré-ajusteEliminar...A eliminar ficheiroA eliminar ficheirosPouco negritoDescriçãoDetalhesDiretório:InativoDiscoMostrar nome da faixa atual na barra de títuloE&xpressãoEditar estação de rádioEditar lista de reproduçãoEditar informações da faixaEditar…Editar… Editar… F2 Editar informações da faixaCodificação:SistemaEqualizadorEqualizador Equalizador:ErroErro ao copiar ficheiroErro ao eliminar ficheiroErro ao ligar ao ficheiroErro ao mover ficheiroErro ao carregar coleção/"plug-in"Ex&ataExclusão Filtrar diretórios e/ou ficheiros com base num padrãoExclusão:ExpandidaExportar álbunsExportar artistasExportar por géneroExportar coleção principalExportar lista de reproduçãoExportar faixasExportar faixas deste álbum para o diretórioExportar faixas deste artista para o diretórioExportar faixas para o diretórioExportar faixas deste género para o diretórioExportar…Extra negritoExtra condensadaExtra expandidaExtra suaveFalha ao carregar o controlador áudio: %sErro fatalF&iltro:O ficheiro já existe. Pretende substituir?Ficheiro não encontradoO ficheiro ou diretório %s já existe. Ficheiro:Nome do ficheiroNome do ficheiro modeloOs nomes não necessitam de ser alteradosFicheiros:Procurar… Ctrl-F Mostrar filtro de procuraPastas:Letras e íconesPor alguma razão a biblioteca FOX foi compilada sem suporte a PNG. Para mostrar todos os ícones, o Goggles necessita do suporte a PNG disponibilizado pela biblioteca FOX. Se foi você que compilou o FOX, verifique se ficheiros libpng estão instalados.Reprodução GaplessGéneroGrandesO Goggles Music Manager não conseguiu abrir a base de dados. É possível que a base de dados esteja danificada. Remova o ficheiro ~/.goggles/goggles.db e tente novamente. Se este erro voltar a ocorrer, reporte-o em http://code.google.com/p/gogglesmmGrupoCarregadaFicheiros ocultosRealce Cor de realceDiretório pessoalTom:ÍconesIgnorar capitularesIgnorar as palavrasImportar pasta… Ctrl-O Importar músicas de uma pasta para a coleçãoImportar músicasImportar lista de reproduçãoImportar lista de reprodução… Importar lista de reproduçãoImportar faixas Importar ficheiros não existentes na base de dadosA importar ficheiros...Importar…Informações… Estatísticas da coleçãoRádio na internetModelo inválidoÍtalicoManter listas de reproduçãoÍcones grandesErro last.fmLast.fmErro na coleçãoSuaveLigaçãoLigar ficheiroCria ligação de: %s para:Ligação...EndereçoLocalização:MinúsculasExtensão de minúsculasMagenta:ManualMédiaMédiasMenu Cor do menuMenu Cor do texto do menuData de modificaçãoSe modificadas desde a última importação Reanalisar detalhes dos ficheiros modificadosPara baixoMover ficheiroPara cimaMover ficheiro de: %s para:Mover...ColeçãoInformações da coleçãoNomeIncapaz de ligar à redeNova estação de rádioNova lista de reprodução… Criar nova lista de reproduçãoNova lista de reproduçãoNova lista de reprodução… Criar lista de reproduçãoNova estação de rádio… Criar lista de reproduçãoNova estação… Novas faixas:Novo diretório...SeguinteSeguinte Reproduzir faixa seguinte Reproduzir faixa seguinteFaixa seguinteFaixa seguinte Ctrl-] Reproduzir faixa seguinteSem alteraçõesNenhuma faixa foi alterada. Ainda assim, pretende gravar os detalhes das faixas selecionadas?N.ºNormalNormal Cor de texto normalNormaisOblíquaDesligadoOops. Erro na base de dadosAbrir local da pasta Abrir local da pastaOpções:Substituir ficheiro?Substituir pré-ajusteAnte&riorDefiniçõesAnalisar de:Senha:PausaPausa Pausa Pausar reproduçãoPausar reproduçãoPausar reproduçãoReproduzirReproduzir Ctrl-P Iniciar reproduçãoReproduzir Iniciar reprodução Iniciar reproduçãoReproduzir ficheiro ou emissãoReproduzir ficheiro ou emissão… Reproduzir ficheiro ou emissãoReproduçãoErro de reproduçãoControlosEm reprodução Cor da faixa em reproduçãoIndique o nome do pré-ajusteIndique o ficheiro ou URL a reproduzir:Por favor, aguarde. Pode levar algum tempo.AmplificadorPreferênciasPreferências%s já existe. Pretende substituir o pré-ajuste?NomePré-ajustes:Ver imagensAnteriorAnterior Reproduzir faixa anterior Reproduzir faixa anteriorFaixa anteriorFaixa anterior Ctrl-[ Reproduzir faixa anteriorFilaSairSubs&tituir tudoErro de leituraSó leituraProntoRemover RemoverRemover álbum?Remover todas as faixas Remover todas as faixas da coleçãoRemover artista?Remover ficheiros áudio...Remover ficheiros áudio?Remover género?Remover da coleção as estações de rádio?Remover estações de rádio?Remover lista de reproduçãoRemover faixa(s)?Remover todas as faixas da coleção?Remover faixa(s) da coleção?Remover faixa(s) da lista de reprodução?Remover da base de dados as faixas encontradas na pastaRemover este álbum da coleção?Remover este álbum da lista de reprodução?Remover da coleção as faixas deste artista?Remover da lista de reprodução as faixas deste artista?Remover faixas do disco rígidoRemover faixas da coleçãoRemover faixas que foram eliminadas do discoRemover da coleção as faixas deste género?Remover da lista de reprodução as faixas deste género?Remover… Del Remover género da coleção.Remover… Del Remover da coleção as faixas relacionadasRemover… Del Remover faixa(s) da coleçãoRemover… Del Remover faixa(s) da lista de reproduçãoMudar nome dos ficheiros?A mudar nome dos ficheiros...Repetir ARepetir A-BRepetir A-B Ctrl-T Repetir secção da faixaRepetir todas Ctrl-/ Repetir todas as faixasNão repetir Ctrl-, Não repetir faixaRepetir faixa Ctrl-. Repetir faixa atualSu&bstituir por:Substituir espaços por "underscores"Substituir "underscores" por espaçosReplay Gain:Incapaz de aceder ao recurso. Veja as permissõesInverterÍtálico invertidoOblíqua invertidaLinhasP&esquisar:FrequênciaSaturação:"Scrobble"Aviso de segurançaSelecione o ficheiroSelecione o tipo de letraSelecionar tudoSeleção Cor do texto da seleçãoPouco condensadaPouco expandidaServiço:Bus de sessão indisponível. Todas as funções sessionbus estão inativas.Canal de transmissão indisponível. Todas as funções Dbus estão inativas.Definir marcadorDefinir modelo...Definir número da faixa com base na ordemConfigurar intervaloSombra Cor da sombraMostrar &género Ctrl-G Mostrar géneroMostrar fonte&s Ctrl-S Mostrar fontesMostrar exploradorMostrar ecrã completo F12 Trocar modo de ecrã completoMostrar ícones no explorador de faixasMostrar textoMostrar reprodutor pequeno Ctrl-M Trocar esquema de reprodutorMostrar barra de estadoMostrar notificação de alteração de faixa Mostrar notificações ao alterar de faixaMostrar ícone na bandeja Mostrar ícone na bandeja do sistemaMostrar capa de álbum da faixa em reprodução Mostrar capa de álbum da faixa em reproduçãoMostrar capa de álbum no explorador de álbuns Mostrar capa de álbum no explorador de álbunsBaralhar Ctrl-RBaralhar Alt-R Reproduzir faixas aleatoriamenteTamanhoIgnorar tod&asIntervaloIntervalo Configurar intervaloParar emÍcones pequenosOpções de ordemOrdenar porOrdenar por anoOrdenaçãoFontes Prima para alterar a ordem Prima para alterar a ordemIndique o nome da nova listaIndique o URL e a descrição da estaçãoIniciar reproduçãoIniciar reproduçãoEstaçãoPararParar Ctrl-\ Parar reproduçãoParar Parar reprodução Parar reproduçãoParar reprodução após um intervalo de tempoEstiloSincronizar pasta… Sincronizar pasta com as músicas da coleçãoSincronizaçãoSincronizar pastaBandeja do sistemaDetalhesDetalhes Prima para alterar a ordem Prima para alterar a ordemOs modelos podem conter caminhos absolutos ou relativos, variáveis de ambiente e ~. Os caminhos relativos têm como base o local do ficheiro. A extensão de ficheiro é adicionada automaticamente. Pode utilizar as seguintes macros:Modelo:Estes ficheiros áudio vão ser removidosO nome dos seguintes ficheiros vai ser alterado:O modelo indicado é inválido. Deve indicar %%T como título da faixa. Corrija o nome do modelo no painel de preferências.EstreitaA last.fm não possui suporte a esta versão do Goggles Music Manager. Deve atualizar o Goggles Music Manager. DuraçãoTítuloFormato do título:Dicas Cor das dicasEm cimaTempo total:FaixaFaixas:Bandeja Cor de fundo da bandejaDesligar sistema de reprodução ao pararLigar sistema de reprodução ao iniciar Para um início mais rápido, o sistema de som é iniciado ao reproduzir a primeira faixa Para um início mais rápido, o sistema de som é iniciado ao reproduzir a primeira faixaTipoUltra condensadaUltra expandidaIncapaz de copiar: %s para: %s Continuar?Incapaz de criar o diretório %s Incapaz de eliminar: %s Continuar?Incapaz de iniciar o sistema de somIncapaz de inserir a faixa na base de dadosIncapaz de iniciar o navegador webIncapaz de criar ligação de: %s para: %s Continuar?Incapaz de mover: %s para: %s Continuar?Incapaz de abrir a base de dadosIncapaz de remover o álbumIncapaz de remover o artistaIncapaz de remover o géneroIncapaz de remover a estação da coleçãoIncapaz de remover a(s) faixa(s)Incapaz de mudar o nomeIncapaz de mudar o nome de: %s para: %sIncapaz de mudar o nome de: %s para: %s Continuar operação?Incapaz de atualizar faixaErro desconhecidoDispositivo desconhecidoServidor desconhecidoSem nomeSubir um nívelAtualizar nome de ficheiroAtualizar detalhes no ficheiroAtualizar detalhes?Atualizar faixas existentes:Atualizar URL e descrição da estaçãoA atualizar base de dados...UtilizadorUtilizador:Valor:VerNormalização de volumeAvisoJanelaDiretório de trabalhoAnoAmarelo:A sua coleção possui...CF ALT Cor de fundo alternativaCP Cor principalCF Cor de fundohoras eminutos…gogglesmm-0.12.7/po/hu.po0000644000175000001440000020707111524673460013716 0ustar sxjusers# Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the gogglesmm package. # # Sándor Sipos , 2010. msgid "" msgstr "" "Project-Id-Version: hu\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2010-08-30 11:52+0200\n" "Last-Translator: Sipos Sándor \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Bezár" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Oszlopok beállítása" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Ok" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Mégsem" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Válassza ki a zeneszámok listájának \n" "rendezési sorrendjét." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Felfelé mozgat" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Lefelé mozgat" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Rossz sablon" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" "A megadott sablon rossz! A szám címét %%T szükséges megadni. \n" "Kérjük javítsa ki a sablont a Beállítások ablakban." #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Adatbázis hiba" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Húha! Adatbázis hiba!" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Nincs változás" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "A fájlnév változatlan" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Átnevezzem a hangfájlokat?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Hangfájlok átnevezése…" #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "A következő hangfájlok kerülnek átnevezésre" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "Át&nevezés" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "A fájl átnevezése sikertelen" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "A fájl átnevezése sikertelen:\n" "%s\n" "\n" "az új névre:%s\n" "Folytassuk a fájlok átnevezését?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "A fájl átnevezése sikertelen:\n" "%s\n" "\n" "az új névre:%s" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Fájlnév sablonok" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "A sablon tartalmazhat relatív, vagy abszolút útvonalat, környezeti változót\n" "és ~ jelet. A relatív útvonalak alpjául a fájl eredeti helye szolgál.\n" "A kiterjesztést automatikusan hozzáadja a program. A következő makrók " "használhatók:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - Cím\t\t\t\t\t\t\t%A - Album címe\n" "%P - Album előadója\t\t\t\t%p - Szám előadója\n" "%y - Év\t\t\t\t\t\t\t%d - lemez száma\n" "%N - Zeneszám sorszáma (2 jegy)\t%n - Zeneszám sorszáma\n" "%G - Műfaj" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "Feltételek is alkalmazhatók:" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" "?c \t- Mutassa a-t, ha c nem üres, egyéb esetekben b-t.\n" "?c\t\t\t- Mutassa c-t, ha az nem üres.\n" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Sablon:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Kódolás:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Kivéve:" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Beállítások:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Szóközök kicserélése alsóvonalra" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Kisbetűs" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Kisbetűs kiterjesztés" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "No." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Sor" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Cím" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Előadó" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Album előadója" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Album" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Lemez" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Műfaj" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Év" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Idő" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Törlés…\tDel\tA műfaj eltávolítása a gyűjteményből." #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Másolás\tCtrl-C\tA kijelölt számok másolása a vágólapra." #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Törlés…\tDel\tA kijelölt számok eltávolítása a gyűjteményből." #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Szerkesztés…\tF2\tZeneszám információinak szerkesztése" #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Másolás\tCtrl-C\tSzám(ok) másolása a vágólapra." #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Törlés…\tDel\tA szám(ok) eltávolítása a gyűjteményből." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Új lejátszólista…\t\tÚj lejátszólista létrehozása." #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Exportálás…" #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Információk…\t\tGyűjtemény statisztika" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "Mindet töröl\t\tAz összes zeneszám eltávolítása a gyűjteményből." #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Szám információk szerkesztése" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "Menté&s" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Tulajdonságok" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Fájlnév" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Típus" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Méret" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Bitráta" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Mintavételezés" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Csatornák" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Szám" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tKülönböző előadók" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tKözös előadók" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Automatikus sorszámozás. Eltolás:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Címkék (Tag) frissítése a fájlban" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Fájlnév frissítése" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Exportálási sablon…" #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Frissítsem a címkéket (Tag)?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Nem változott egyetlen szám sem.\n" "Továbbra is szeretné a címkék frissítését a kijelölt számokra?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Töröljem a hangfájlokat?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "A hangfájlok eltávolítása..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "A következő hangfájlokat fogom törölni" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Törlés" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Fő gyűjtemény exportálása" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Lejátszólista exportálása" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Felülírjam a fájt?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "A fájl már létezik. Felülírjam a fájlt?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Műfaj exportálása" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Számok exportálása könyvtárba műfajuk alapján." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Előadók exportálása" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Számok exportálása könyvtárba előadójuk alapján." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Albumok exportálása" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Számok exportálása könyvtárba albumuk alapján." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Számok exportálása" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Számok exportálása könyvtárba." #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Exportálás" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Eltávolítsam a műfajt?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Eltávolítsam az adott műfajú zenéket a gyűjteményből?" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Töröljem az előadót?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Töröljem az előadó összes számát a gyűjteményből?" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Töröljem az albumot?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Töröljem az albumhoz tartozó összes számot a gyűjteményből?" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Töröljem a számo(ka)t" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Töröljem a számo(ka)t a gyűjteményből?" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Számok törlése a lemezről" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Gyűjtemény hiba" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "A műfaj eltávolítása az adatbázisból sikertelen." #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Az előadó eltávolítása az adatbázisból sikertelen." #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Az album eltávolítása az adatbázisból sikertelen." #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "A zeneszám eltávolítása az adatbázisból sikertelen." #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Lejátszólista létrehozása" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Adja meg az új lejátszólista nevét" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Létrehozás" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Név" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Új lejátszólista" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Töröljük a Zenei gyűjteményt?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Eltávolítsuk az összes számot a gyűjteményből?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Összes eltávolítása" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Lejátszólisták megtartása" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Zenei Gyűjtemény információk" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Az Ön zenei gyűjteménye a következőkből áll" #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Számok:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Előadók:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Albumok:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Összes idő:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Hangszínszabályozó" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Hangszínszabályozó:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tMentés" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tAlapállapot" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tTörlés" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Előerősítés" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Letiltva" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Kézi" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Beállítás törlése" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Biztos, hogy törölni akarja a(z) \"%s\" nevű hangszín beállítást?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Beállítás neve" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Adja meg a beállítás nevét:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Beállítás felülírása" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "A(z) \"%s\" beállítás már létezik. Felülírjam?" #: src/GMFontDialog.cpp:209 #, fuzzy msgid "Ultra Condensed" msgstr "Nagyon sűrű" #: src/GMFontDialog.cpp:210 #, fuzzy msgid "Extra Condensed" msgstr "Extra sűrű" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Sűrű" #: src/GMFontDialog.cpp:212 #, fuzzy msgid "Semi Condensed" msgstr "Mérsékelten sűrű" #: src/GMFontDialog.cpp:214 #, fuzzy msgid "Semi Expanded" msgstr "Mérsékelten széthúzott" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Széthúzott" #: src/GMFontDialog.cpp:216 #, fuzzy msgid "Extra Expanded" msgstr "Extra széthúzott" #: src/GMFontDialog.cpp:217 #, fuzzy msgid "Ultra Expanded" msgstr "Ultra széthúzott" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 #, fuzzy msgid "Extra Light" msgstr "extravékony" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 #, fuzzy msgid "Light" msgstr "vékony" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 #, fuzzy msgid "Medium" msgstr "közepes" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 #, fuzzy msgid "Demibold" msgstr "demikövér" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 #, fuzzy msgid "Extra Bold" msgstr "extrabold" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 #, fuzzy msgid "Heavy" msgstr "nehéz" #: src/GMFontDialog.cpp:239 #, fuzzy msgid "Reverse Oblique" msgstr "visszafelé dőlt" #: src/GMFontDialog.cpp:240 #, fuzzy msgid "Reverse Italic" msgstr "visszafelé dőlt" #: src/GMFontDialog.cpp:242 #, fuzzy msgid "Italic" msgstr "dőlt" #: src/GMFontDialog.cpp:243 #, fuzzy msgid "Oblique" msgstr "dőlt" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normál" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "Könyvtár:" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&File név:" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "F&ile szűrő:" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Csak olvasható" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Könyvtár:" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "&Könyvjelző ide\t\tKönyvjelző elhelyezése az aktuális könyvtárra." #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "&Könyvjelzők törlése\t\tKönyvjelzők törlése" #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tEgy könyvtárral feljebb\tEgy könyvtárral feljebb" #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tSaját könyvtár\tSaját könyvtár." #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tMunkakönyvtár\tUgrás a futtatási könyvtárba" #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tKönyvjelzők\tA könyvjelzők megtekintése." #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tÚj könyvtár létrehozása\tÚj könyvtár létrehozása" #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tLista\tA könyvtár tartalmának megjelenítése listaként." #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tIkonok\tA könyvtár tartalmának megjelenítése nagy ikonok formájában." #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tRészletek megjelenítése\tRészletes könvtárlista megjelenítése." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "" "\tRejtett fájlok megjelenítése\tRejtett fájlok és könyvtárak megjelenítése." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "" "\tRejtett fájlok rejtése\tNe mutassa a rejtett fájlokat és könyvtárakat." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Könyvtár szinkronizálása" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "Lejátszólista exportálása" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Zenék importálása" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Fájl(ok)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Könyvtár" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "" "Kizáró szűrő\tHagyja ki azokat a fájlokat/könyvtárakat amelyre teljesül a " "szűrő" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Könyvtárak:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Fájlok:" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Szinkronizálás" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Szinkronizálás" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" "Új számok importálása\tImportálja azon fájlokat, amelyek eddig nem " "szerepeltek a gyűjteményben." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "" "Számok eltávolítása a gyűjteményből, melyek már nem találhatók a lemezen" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Meglévő számok frissítése" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" "Módosult a legutóbbi importálás óta\tCsak a címkék (Tag) újraolvasása " "azoknál a fájloknál, amelyek a legutóbbi import óta módosultak." #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Összes\tMindig olvassa be a címkéket (Tag)" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "A könyvtárban található számok eltávolítása a gyűjteményből" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Szám" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Beállítások beolvasása" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Beállítások beolvasása innen:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Címke" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Mindkettő" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Alapértelmezett érték:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "A szám sorszáma a beolvasás sorrendje szerint" #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - cím %A - album cím\n" "%P - album előadója %p - szám előadója \n" "%N - szám sorszáma %G - műfaj" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Alsóvonalakat cserélje szóközre" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Importálás" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Nem tudom inicializálni a lejátszót." #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Ismeretlen host." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Ismeretlen eszköz" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "A hálózat nem elérhető." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "A hangkimenet nem elérhető." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Kapcsolódás visszautasítva." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "A fájl nem található." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Az erőforrás nem elérhető. Ellenőrizze a jogosultságokat." #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Olvasási hiba" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Hiba a könyvtár/kiegészítő betöltése során." #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Figyelmeztetés" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Biztonsági figyelmeztetés" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Ismeretlen hiba" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Hiba" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Nem tudom létrehozni a(z) \"%s\" könyvtárat\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Valamilyen okból kifolyólag a FOX PNG támogatás nélkül került lefordításra.\n" "Ahhoz, hogy az összes ikon megjeleníthető legyen, szükség van a PNG " "támogatásra. \n" "Ha a FOX könyvtárat Ön fordította, ellenőrizze, hogy a libpng fejlesztői " "fájlok telepítve legyenek a FOX lefordításakor." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "A session busz nem elérhető. A dbus-t igénylő funkciókat kikapcsoltam." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "DBus hiba keletkezett. A dbus-t igénylő funkciókat kikapcsoltam." #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "A session busz nem elérhető. A dbus-t igénylő funkciókat kikapcsoltam." #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Hangeszköz hiba" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Last.FM hiba." #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Lejátszási hiba" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Törlés…\tDel\tA szám eltávolítása a lejátszólistából." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Szerkesztés…" #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "Importálás…" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Lejátszólista eltávolítása" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Eltávolítsuk az ilyen műfajú számokat a lejátszólistából?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Eltávolítsuk az előadóhoz tartozó számokat a lejátszólistából?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Eltávolítsuk az albumhoz tartozó számokat a lejátszólistából?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Eltávolítsuk a számokat a lejátszólistából?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Számok eltávolítása a lejátszólistából" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Lejátszólista szerkesztése" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Lejátszólista nevének megváltoztatása" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Töröljem a lejátszólistát?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Biztos benne, hogy töröljem a lejátszólistát?" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Igen" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Nem" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Beállítások" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Általános" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Rendezési beállítások" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Névelők figylemen kívül hagyása" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Album borítók" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" "Mutassa az albumborítót a szám lejátszásakor\tMutassa a lejátszott szám " "ablumborítóját." #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" "Albumborítók megjelenítése az albumböngészőben\tAlbumborítók megjelenítése " "az albumböngészőben" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "Tálca" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Tálca ikon használata\tMutassa a kis tálca ikont." #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" "Számváltás üzenetpanel\tÜzenetet küld a notification daemonnak,hogy más " "számot játszik már a program." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "A Goggles Music Manager ezen verziója\n" "nem támogatott a Last.fm által. Frissítsen\n" "egy frissebb verziójú programra." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 #, fuzzy msgid "&Sign up…" msgstr "&Feliratkozás last.fm-re…" #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Felhasználónév:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Jelszó:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Ablak" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Ablak" #: src/GMPreferencesDialog.cpp:365 #, fuzzy msgid "Close button minimizes to tray" msgstr "A bezáró gomb elrejti a főablakot" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Állapotsor megjelenítése" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Ikonok a zeneszám böngészőben" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "A lejátszott szám információinak megjelenítése a címsorban" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Lejátszó gombok" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Hely:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Tetejére" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Aljára" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Stílus" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Gombfeliratok megjelenítése" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Nagy ikonok" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "&Megjelenés" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Színek" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "elő\tElőtér színe" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "hát\tHáttér színe" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt\tAlternatív szín" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normál\tNormál betűszín" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Alap\tAlap szín" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Kijelölt\tKijelölt szöveg színe" #: src/GMPreferencesDialog.cpp:433 #, fuzzy msgid "Menu\tMenu Base Color" msgstr "Menü\tMenü színe" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menü\tMenü színe" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Keret\tKeret színe" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Súgó\tSúgó színe" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Aktuális\tAktuális menüpont színe" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Árnyék\tÁrnyék színe" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Lejátszott\tAz éppen lejátszott szám színe" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "Tálca\tTálca háttér színe" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Beállítás:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 #, fuzzy msgid "Default Font" msgstr "Alapértelmezett érték:" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Változtatás…" #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Ikonok" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Hang" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Lejátszó modul" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Hangeszköz" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Zárja le a hangeszközt szünetre" #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Kapcsolja ki a lejátszó modult leállításkor" #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" "Kapcsolja be a lejátszó modult induláskor\tA gyorsabb indulás érdekében a " "lejátszó modul csak az első szám lejátszásakor kerül elindításra.\tA " "gyorsabb indulás érdekében a lejátszó modul csak az első szám lejátszásakor " "kerül elindításra." #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Lejátszás" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Lejátszás vezérlés" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "Kikapcsol" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Szünetmentes lejátszás" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Hangerő normalizálása" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "A(z) %s hangeszköz megnyitása sikertelen." #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Aktuális" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Egyedi" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Nem tudtam elindítani a böngészőt" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Normál betűtípus kiválasztása" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Következő" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "&Előző" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Lejátszás" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "Áll&j" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Böngésző megjelenítése" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Kilépés" #: src/GMRemote.cpp:385 #, fuzzy msgid "\tShow Browser\tShow Browser" msgstr "Böngésző megjelenítése" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tLejátszás\tLejátszás" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tLejátszás megállítása\tLejátszás megállítása" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tElőző szám lejátszása\tElőző szám lejátszása" #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tKövetkező szám lejátszása\tKövetkező szám lejátszása" #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tHangerő beállítása\tHangerő beállítása" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Nem tudom az adatbázist megnyitni." #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "Adatbázis hiba: Nem tudom a fájlneveket kiolvasni." #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "A szám adatainak frissítése sikertelen." #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Nem tudom a zeneszámot az adatbázisba írni!" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Súlyos hiba" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Kérem vegye fel a fejlesztővel a kapcsolatot, ha ez a hiba többször is " "előfordul." #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Adatbázis frissítése…" #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Kérem várjon. Ez eltarthat egy ideig." #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Új számok:" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "Fájl:" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Fájlok importálása…" #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "Importálás megállítá&sa" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" "Források\tNyomja meg a sorrend megváltoztatásához\tNyomja meg a sorrend " "megváltoztatásához" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Új lejátszólista…\t\tÚj lejátszólista létrehozása" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "Lejátszólista importálása…\t\tLétező lejátszólista importálása" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Új rádióállomás…\t\tÚj rádióállomás hozzáadása" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Rádióállomás" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Új Rádióállomás…\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Szerkesztés…\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Törlés\t\tTörlés" #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Új Internetes Rádióállomás" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Adja meg az új rádióállomás címét és leírását" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "&Létrehozás" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "Cím" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "Leírás" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Névtelen" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Internetes Rádióállomás szerkesztése" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Adja meg a rádióállomás URL-jét és leírását" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Eltávolítsam az Internetes Rádióállomás(oka)t?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Eltávolítsam az Internetes Rádióállomás(oka)t a gyűjteményből?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Nem tudom a rádióállomást eltávolítani a gyűjteményből!" #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" "Inkompatibilis (jövőbeli verziószámmal rendelkező) adatbázist találtam! \n" "Ez általában akkor fordulhat elő, ha a korábban használtnál régebbi GMM " "változatot telepített.\n" "Nyomjon OK-t az adatbázis eldobásához (minden ott tárolt információ elvész)\n" "Nyomjon \"Mégsem\"-et a kilépéshez, az adatbázis meghagyásához." #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" "Goggles Music Manager nem tudta megnyitni az adatbázist.\n" "Az adatbázis fájl megsérülhetett. Kérem, törölje a \"~/.goggles/goggles.db\" " "fájlt és próbálja újból.\n" "Ha a hiba továbbra is elfordul, kérem, tegyen hibabejelentést a http://code." "google.com/p/gogglesmm címen." #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tSzűrő bezárása\tSzűrő bezárása" #: src/GMTrackView.cpp:246 #, fuzzy msgid "&Find" msgstr "Keresés" #: src/GMTrackView.cpp:252 #, fuzzy msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" "Műfajok\tNyomja meg a sorrend megváltoztatásához\tNyomja meg a sorrend " "megváltoztatásához" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" "Előadók\tNyomja meg a rendezés megváltoztatásához\tNyomja meg a rendezés " "megváltoztatásához" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" "Albumok\tNyomja meg a sorrend megváltoztatásához\tNyomja meg a sorrend " "megváltoztatásához" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "Oszlopok &beállítása" #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Böngészés" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Keverés\tCtrl-R" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Visszafelé" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Az összes (%d db) műfaj" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Összes műfaj" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Az összes (%d db) előadó" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Az összes (%d db) album" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "%s alapján" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Rendezés az album (kiadási) éve alapján" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Oszlopok\t\tLátható oszlopok beállítása." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "Rendezé&s\t\tRendezés beállítása." #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "Lejátszás" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "Állj" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Előző szám" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Következő szám" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Lejátszás\tA lejátszás elindítása\tA lejátszás elindítása" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Szünet\tA lejátszás megakasztása\tA lejátszás megakasztása" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Állj\tA lejátszás leállítása\tA lejátszás leállítása" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Előző\tAz előző szám lejátszása\tAz előző szám lejátszása" #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Következő\tA következő szám lejátszása\tA következő szám lejátszása" #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Fájl" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" "Könyvtár importálása…\tCtrl-O\tZenék importálása a megadott könyvtárból a " "gyűjteménybe" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "Szinkronizálás…\t\tA könyvtár szinkronizálása a gyűjteménnyel" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "&Kilépés\tCtrl-Q\tKilépés a programból" #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "Sz&erkesztés" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Másolás\tCtrl-C\tKijelölt fájlok másolása" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "&Kivágás\tCtrl-X\tKijelölt fájlok kivágása" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "&Beillesztés\tCtrl-V\tBeillesztés a vágólapról." #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Keresés…\tCtrl-F\tKeresőszűrő megjelenítése." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Beállítások…" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Nézet" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "&Böngészés\tCtrl-B\tMűfaj, előadó, album böngésző megjelenítése." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "&Műfajok megjelenítése\tCtrl-G\tMűfajböngésző megjelenítése." #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Források megjelenítése\tCtrl-S\tForrás böngésző megjelenítése." #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Teljes képernyő\tF12\tTeljes képernyő ki/bekapcsolása." #: src/GMWindow.cpp:296 #, fuzzy msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Mini lejátszó\tF11\tMini lejátszó üzemódba kapcsolás" #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Rendezés" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "" "&Ugrás az aktuális számra\tCtrl-J\tAz éppen lejátszott számra ugrik a " "listában." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Lejátszás" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Lejátszás\tCtrl-P\tLejátszás megkezdése" #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Állj\tCtrl-\\\tA lejátszás megállítása" #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Előző szám\tCtrl-[\tElőző szám lejátszása" #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Következő szám\tCtrl-]\tA következő szám lejátszása." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Ismétlés kikapcsolása\tCtrl-,\tNem ismétli a számokat." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Szám ismétlése\tCtrl-.\tAz aktuális szám ismétlése." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Összes ismétlése\tCtrl-/\tAz összes számot ismétli." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Szám egy részének ismétlése\tCtrl-T\tA szám egy részének ismétlése" #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Véletlenszerűen\tAlt-R\tA számok véletlenszerű lejátszása." #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Hangszínszabályozó\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Sleep funkció\t\tSleep funkció beállítása" #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Segítség" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Honlap" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "Hiba &bejelentése" #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Feliratkozás last.fm-re…" #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" "&Csatlakozás a GMM-hez a last.fm-en…\t\tCsatlakozás a last.fm GMM " "csoportjához." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&A programról…" #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "Szünet" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Előző" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Következő" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "Lejátszás." #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 msgid "Start playback" msgstr "Lejátszás" #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Szünet" #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "Szünet" #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Szám egy részének ismétlése" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Szám egy részének megjelölése" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "Kérem adja meg a lejátszandó file-t, vagy címet:" #: src/GMWindow.cpp:1206 msgid "…" msgstr "…" #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "Fájl kiválasztása" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Sleep időzítő" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Sleep időzítő beállítása" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Lejátszás megállítása ennyi idő után" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "Időzítő indítá&sa" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Kapcsoljon ki " #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "óra és" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "perc múlva." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Zenei gyűjtemény" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Internet Rádió" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Kilépés" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Kihagyás" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Min&dent kihagy" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Nincs mentés" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tSzín kiválasztása" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tSzín, telítettség, fényerő" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tPiros, Zöld, Kék" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Piros:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Zöld:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Kék:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Szín:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Telítettség:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Fényerő:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tCián, Magenta, Sárga" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Cián:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Magenta:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Sárga:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tNév szerint" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Új könyvtár létrehozása" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Már létezik" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Nem tudtam létrehozni" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Fájl másolása" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Hiba a másolás során" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Fájl mozgatása" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Hiba a mozgatás során" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Hivatkozás" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Hiba a hivatkozás létrehozásakor" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Fájl törlése" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Hiba a törlés során" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Egy szinttel feljebb" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Saját könyvtár" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Futtatási könyvtár" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Rendezés" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "kisbetű/Nagybetű" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Rejtett fájlok" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Könyvjelzők" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Könyvjelző létrehozása" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Könyvjelzők törlése" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Új könyvtár..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Másolás..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Mozgatás..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Hivatkozás..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Törlés..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Módosítás dátuma" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Felhasználó" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Csoport" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Tulajdonságok" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Hivatkozás" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Új könyvtár létrehozása a következő névvel:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "A %s fájl vagy könyvtár már létezik.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Nem tudtam a %s könyvtárat létrehozni.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Fájl másolása innen:\n" "\n" "%s\n" "\n" "ide: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "A fájl másolása sikertelen:\n" "\n" "%s ide: %s\n" "\n" "Folytassam a műveletet?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "A fájl mozgatása innen:\n" "\n" "%s\n" "\n" "ide:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "A fájl mozgatása sikertelen:\n" "\n" "%s ide: %s\n" "\n" "Folytassam a műveletet?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "A fájl hivatkozása innen:\n" "\n" "%s\n" "\n" "ide:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "A fájl hivatkozása sikertelen:\n" "\n" "%s fájlt ide: %s \n" "\n" "Folytassam a műveletet?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Fájlok törlése" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Biztos, hogy törölni akarja a fájlt:\n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "A fájl törlése sikertelen:\n" "\n" "%s\n" "\n" "Folytassam a műveletet?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Mindet kijelöl" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Rendezés" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Nézet" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Kis ikonok" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Nagy ikonok" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Részletek" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Sorok" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Oszlopo" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Előnézeti képek" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Normál méretű képek" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Közepes képek" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Nagy képek" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Csere" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Cserélje &mindet" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "Keresse e&zt" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Csere e&rre:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "&Teljes" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Nagybetűérzékeny" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "Ki&fejezés" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Visszafelé" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Keresés" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Ok." #~ msgid "Old Name" #~ msgstr "Régi név" #~ msgid "New Name" #~ msgstr "Új név" #~ msgid "Pitch:" #~ msgstr "Szélesség:" #~ msgid "Any" #~ msgstr "Bármilyen" #~ msgid "Fixed" #~ msgstr "Fix" #~ msgid "Variable" #~ msgstr "Változó" #, fuzzy #~ msgid " Type:" #~ msgstr "Típus" #, fuzzy #~ msgid "Scalable" #~ msgstr "Átméretezhető:" #, fuzzy #~ msgid "Size:" #~ msgstr "Méret" #, fuzzy #~ msgid "Family:" #~ msgstr "&Család" #~ msgid "Always Show Remote" #~ msgstr "Mindig látszódjon a mini lejátszó" #~ msgid "Source\tActive Source Color" #~ msgstr "Forrás\tAktív forrás színe" #~ msgid "About" #~ msgstr "A programról" #~ msgid "" #~ "An incompatible version of SQLite (%s) is being used.\n" #~ "Goggles Music Manager requires at least SQLite 3.3.8.\n" #~ "Please upgrade your SQLite installation." #~ msgstr "" #~ "Nem támogatott SQLite verziót (%s) találtam.\n" #~ "A Goggle Music Manager legalább 3.3.8-as SQLite-t igényel.\n" #~ "Kérem frissítse az SQLite-ot!" #~ msgid "" #~ "This version of SQLite (%s) is broken.\n" #~ "Please upgrade your SQLite installation to at least 3.6.3." #~ msgstr "" #~ "Az SQLite ezen verziója(%s) rossz.\n" #~ "Kérem frissítsen legalább SQLite 3.6.3-ra." #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "&Csatlakozás GMM csoporthoz a last.fm-en…\tCsatlakozás GMM csoporthoz a " #~ "last.fm-en…\tCsatlakozás GMM csoporthoz a last.fm-en…" #~ msgid "Font" #~ msgstr "Betűtípus" #~ msgid "Theme Directory:" #~ msgstr "Téma könyvtár:" #~ msgid "Select Theme Directory" #~ msgstr "Válassza ki a téma könyvtárát" #~ msgid "thin" #~ msgstr "vékony" #~ msgid "normal" #~ msgstr "normál" #~ msgid "bold" #~ msgstr "félkövér" #~ msgid "regular" #~ msgstr "általános" #~ msgid "&Weight:" #~ msgstr "&Vastagság" #~ msgid "&Style:" #~ msgstr "&Stílus" #~ msgid "Si&ze:" #~ msgstr "&Méret:" #~ msgid "Character Set:" #~ msgstr "Karakter kód:" #~ msgid "West European" #~ msgstr "Nyugat Európai" #~ msgid "East European" #~ msgstr "Kelet-Európai" #~ msgid "South European" #~ msgstr "Dél-Európai" #~ msgid "North European" #~ msgstr "Észak-Európai" #~ msgid "Cyrillic" #~ msgstr "Cirill" #~ msgid "Arabic" #~ msgstr "Arab" #~ msgid "Greek" #~ msgstr "Görög" #~ msgid "Hebrew" #~ msgstr "Héber" #~ msgid "Turkish" #~ msgstr "Török" #~ msgid "Nordic" #~ msgstr "Északi" #~ msgid "Thai" #~ msgstr "Thai" #~ msgid "Baltic" #~ msgstr "Balti" #~ msgid "Celtic" #~ msgstr "Kelta" #~ msgid "Russian" #~ msgstr "Orosz" #~ msgid "Central European (cp1250)" #~ msgstr "Közép-Európai (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Orosz (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Latin1 (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Görög (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Török (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Héber (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Arab (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Balti (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Vietnámi (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Thai (cp874)" #~ msgid "UNICODE" #~ msgstr "UNICODE" #~ msgid "Set Width:" #~ msgstr "Betűköz/Szélesség:" #~ msgid "All Fonts:" #~ msgstr "Minden betű:" #~ msgid "Preview:" #~ msgstr "Előnézeti képek:" gogglesmm-0.12.7/po/cs.po0000644000175000001440000020514711525025727013707 0ustar sxjusers# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.0\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2011-02-10 19:05+0100\n" "Last-Translator: David Vachulka \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" #: src/GMAbout.cpp:136 #: src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 #: src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "&Zavřít" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Konfigurace sloupců" #: src/GMColumnDialog.cpp:207 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Přijmout" #: src/GMColumnDialog.cpp:208 #: src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 #: src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 #: src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 #: src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 #: src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 #: src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 #: src/GMStreamSource.cpp:169 #: src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 #: src/GMWindow.cpp:1198 #: src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "Z&rušit" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Vyberte pořadí informací pro zobrazení\n" "v seznamu skladeb." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Posunout nahoru" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Posunout dolů" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Neplatná šablona" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be specified.\n" "Please fix the filename template in the preference panel." msgstr "" "Daná šablona není platná. Jméno skladby %%T musí být definováno.\n" "Upravte šablonu v panelu nastavení." #: src/GMDatabaseSource.cpp:72 #: src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Chyba databáze" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Ajaj. Chyba databáze" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Beze změn" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Jména souborů nevyžadují žádnou změnu" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Přejmenovat audio soubory?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Přejmenování audio souborů..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "Následující audio soubory budou přejmenovány" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "&Přejmenovat" #: src/GMDatabaseSource.cpp:121 #: src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Nemohu přejmenovat soubor" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "Nemohu přejmenovat:\n" "%s\n" "\n" "na:%s\n" "Pokračovat v přejmenování?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "Nemohu přejmenovat:\n" "%s\n" "\n" "na:%s" #: src/GMDatabaseSource.cpp:160 #: src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Šablona jména souboru" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "Šablona může obsahovat absolutní nebo relativní cestu, proměnné prostředí\n" "a ~. Relativní cesty jsou založeny na umístění souboru.\n" "Přípony souboru budou automaticky přidány. Následující makra\n" "můžou být použity:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - titul %A - jméno alba\n" "%P - jméno interpreta alba\n" "%p - jméno interpreta skladby\n" "%N - číslo skladby (2 místa)\n" "%n - číslo skladby\n" "%G - žánr" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "Podmínky můžou být použity následujícím způsobem:" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" "?c - zobrazí a, jestliže není c prázdné, jinak zobrazí b.\n" "?c - zobrazí c, jestliže není prázdné\n" #: src/GMDatabaseSource.cpp:195 #: src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Šablona:" #: src/GMDatabaseSource.cpp:199 #: src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Kódování:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Vynechat:" #: src/GMDatabaseSource.cpp:209 #: src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Volby:" #: src/GMDatabaseSource.cpp:210 #: src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Nahradit mezery podtržením" #: src/GMDatabaseSource.cpp:212 #: src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Malá písmena" #: src/GMDatabaseSource.cpp:214 #: src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Malá písmena přípony" #: src/GMDatabaseSource.cpp:341 #: src/GMStreamSource.cpp:63 msgid "No." msgstr "Č." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Fronta" #: src/GMDatabaseSource.cpp:343 #: src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Název" #: src/GMDatabaseSource.cpp:344 #: src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Interpret" #: src/GMDatabaseSource.cpp:345 #: src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Interpret alba" #: src/GMDatabaseSource.cpp:346 #: src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 #: src/GMTrackView.cpp:240 msgid "Album" msgstr "Album" #: src/GMDatabaseSource.cpp:347 #: src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 #: src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Disk" #: src/GMDatabaseSource.cpp:348 #: src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 #: src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 #: src/GMTrackView.cpp:241 msgid "Genre" msgstr "Žánr" #: src/GMDatabaseSource.cpp:349 #: src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Rok" #: src/GMDatabaseSource.cpp:350 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Délka" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Odstranit...\tDel\tOdstraní žánr z knihovny." #: src/GMDatabaseSource.cpp:496 #: src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 #: src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Kopírovat\tCtrl-C\tKopíruje asociované skladby do schránky." #: src/GMDatabaseSource.cpp:499 #: src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Odstranit...\tDel\tOdstraní asociované skladby z knihovny." #: src/GMDatabaseSource.cpp:513 #: src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Upravit...\tF2\tUpraví informace o skladbě." #: src/GMDatabaseSource.cpp:514 #: src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Kopírovat\tCtrl-C\tKopíruje skladbu(y) to schránky." #: src/GMDatabaseSource.cpp:518 #: src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "Otevřít adresář\t\tOtevře adresář." #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Odstranit...\tDel\tOdstraní skladbu(y) z knihovny." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Nový seznam skladeb...\t\tVytvoří nový seznam skladeb." #: src/GMDatabaseSource.cpp:539 #: src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Export…" #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Informace...\t\tStatistiky o knihovně" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "Odstranit všechny skladby\t\tOdstraní všechny skladby z knihovny" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Upravit informaci o skladbě" #: src/GMDatabaseSource.cpp:1275 #: src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Uložit" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "&Tag" #: src/GMDatabaseSource.cpp:1320 msgid "&Properties" msgstr "&Vlastnosti" #: src/GMDatabaseSource.cpp:1325 #: src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Jméno souboru" #: src/GMDatabaseSource.cpp:1329 #: ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Typ" #: src/GMDatabaseSource.cpp:1333 #: ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Velikost" #: src/GMDatabaseSource.cpp:1341 #: src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Bitrate" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Samplerate" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Kanály" #: src/GMDatabaseSource.cpp:1358 #: src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Skladba" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tOddělení interpreti" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tSdílení interpreti" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Automatické číslování skladeb. Krok:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Aktualizovat značku v souboru" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Aktualizovat jméno souboru" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Nastavit šablonu pro export..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Aktualizovat značky?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Skladby nebyly aktualizovány.\n" "Chcete stále zapsat značky pro vybrané skladby?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Odstranit audio soubory?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Odstranit audio soubory..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Následující audio soubory budou odstraněny" #: src/GMDatabaseSource.cpp:1703 #: src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 #: src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Odstranit" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Exportovat hlavní knihovnu" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Exportovat seznam skladeb" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Přepsat soubor" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "Soubor už existuje. Chcete ho přepsat?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Exportovat žánr" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Exportovat skladby žánru do daného adresáře." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Exportovat interprety" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Exportovat skladby interpreta do daného adresáře." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Exportovat alba" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Exportovat skladby z alba do daného adresáře." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Exportovat skladby" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Exportovat skladby do daného adresáře." #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Export" #: src/GMDatabaseSource.cpp:1853 #: src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Odstranit žánr?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Odstranit skladby žánru z knihovny?" #: src/GMDatabaseSource.cpp:1858 #: src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Odstranit interpreta?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Odstranit skladby interpreta z knihovny?" #: src/GMDatabaseSource.cpp:1863 #: src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Odstranit album?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Odstranit skladby z alba z knihovny?" #: src/GMDatabaseSource.cpp:1868 #: src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Odstranit skladbu(y)?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Odstranit skladbu(y) z knihovny?" #: src/GMDatabaseSource.cpp:1881 #: src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Odstranit skladby z disku" #: src/GMDatabaseSource.cpp:1895 #: src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 #: src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 #: src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Chyba knihovny" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "Nemohu odstranit žánr z knihovny" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Nemohu odstranit interpreta z knihovny" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Nemohu odstranit album z knihovny" #: src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "Nemohu odstranit skladbu z knihovny." #: src/GMDatabaseSource.cpp:2117 #: src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Vytvořit seznam skladeb" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Zadejte jméno nového seznamu skladeb" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Vytvořit" #: src/GMDatabaseSource.cpp:2125 #: src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Jméno" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Nový seznam skladeb" #: src/GMDatabaseSource.cpp:2178 #: src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Vyčistit knihovnu?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Odstranit všechny skladby z knihovny?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "Odstranit &vše" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Ponechat seznamy skladeb" #: src/GMDatabaseSource.cpp:2212 #: src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Informace o knihovně" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Kolekce hudby se skládá z..." #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Skladby:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Interpreti:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Alba:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Celková délka:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Ekvalizér" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Ekvalizér:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tUložit" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tResetovat" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tOdstranit" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Pre-amp" #: src/GMEQDialog.cpp:244 #: src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Blokovaný" #: src/GMEQDialog.cpp:247 #: src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Ruční" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Smazat nastavení" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Jste si jistý smazáním nastavení %s?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Jméno nastavení" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Vložte jméno nastavení:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Přepsat nastavení" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "Nastavení %s už existuje. Chcete ho přepsat?" #: src/GMFontDialog.cpp:209 msgid "Ultra Condensed" msgstr "Ultra zhuštěné" #: src/GMFontDialog.cpp:210 msgid "Extra Condensed" msgstr "Extra zhuštěné" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Úzké" #: src/GMFontDialog.cpp:212 msgid "Semi Condensed" msgstr "Polo zhuštěné" #: src/GMFontDialog.cpp:214 msgid "Semi Expanded" msgstr "Polo roztažené" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Roztažené" #: src/GMFontDialog.cpp:216 msgid "Extra Expanded" msgstr "Extra roztažené" #: src/GMFontDialog.cpp:217 msgid "Ultra Expanded" msgstr "Ultra roztažené" #: src/GMFontDialog.cpp:224 #: src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "Tenké" #: src/GMFontDialog.cpp:225 #: src/GMPreferencesDialog.cpp:1224 msgid "Extra Light" msgstr "Extra nepatrné" #: src/GMFontDialog.cpp:226 #: src/GMPreferencesDialog.cpp:1225 msgid "Light" msgstr "Nepatrné" #: src/GMFontDialog.cpp:228 #: src/GMPreferencesDialog.cpp:1227 msgid "Medium" msgstr "Střední" #: src/GMFontDialog.cpp:229 #: src/GMPreferencesDialog.cpp:1228 msgid "Demibold" msgstr "Polotučné" #: src/GMFontDialog.cpp:230 #: src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "Tučné" #: src/GMFontDialog.cpp:231 #: src/GMPreferencesDialog.cpp:1230 msgid "Extra Bold" msgstr "Extra tučné" #: src/GMFontDialog.cpp:232 #: src/GMPreferencesDialog.cpp:1231 msgid "Heavy" msgstr "Husté" #: src/GMFontDialog.cpp:239 msgid "Reverse Oblique" msgstr "Obráceně šikmé" #: src/GMFontDialog.cpp:240 msgid "Reverse Italic" msgstr "Obrácená kurzíva" #: src/GMFontDialog.cpp:242 msgid "Italic" msgstr "Kurzíva" #: src/GMFontDialog.cpp:243 msgid "Oblique" msgstr "Šikmé" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normální" #: src/GMImportDialog.cpp:91 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "&Adresář" #: src/GMImportDialog.cpp:166 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&Jméno souboru:" #: src/GMImportDialog.cpp:168 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "F&iltr souborů:" #: src/GMImportDialog.cpp:174 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Jen pro čtení" #: src/GMImportDialog.cpp:179 #: src/GMSearch.cpp:565 #: src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Adresář:" #: src/GMImportDialog.cpp:186 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "&Nastavit záložky\t\tZazáložkuje aktuální adresář." #: src/GMImportDialog.cpp:187 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "&Vyčistit záložky\t\tVyčistí záložky." #: src/GMImportDialog.cpp:203 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tJít o adresář výše\tPřesune do adresáře výše." #: src/GMImportDialog.cpp:204 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tJít do domovského adresáře\tZpátky do domovského adresáře." #: src/GMImportDialog.cpp:205 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tJít do pracovního adresáře\tZpátky do pracovního adresáře." #: src/GMImportDialog.cpp:206 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tZáložky\tNavštíví zazáložkované adresáře." #: src/GMImportDialog.cpp:209 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tVytvořit nový adresář\tVytvoří nový adresář." #: src/GMImportDialog.cpp:210 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tZobrazit seznam\tZobrazí adresář s malými ikonami." #: src/GMImportDialog.cpp:211 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tZobrazit ikony\tZobrazí adresář s velkými ikonami." #: src/GMImportDialog.cpp:212 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tZobrazit detaily\tZobrazí detailní seznam adresářů." #: src/GMImportDialog.cpp:213 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "\tZobrazit skryté soubory\tZobrazí skryté soubory a adresáře." #: src/GMImportDialog.cpp:213 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "\tSkrýt skryté soubory\tSkryje skryté soubory a adresáře." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Synchronizovat složku" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "Načíst seznam skladeb" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Importovat hudbu" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Soubor(y)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Adresář" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "Filtr pro vynechání\tVynechá adresáře a/nebo soubory podle šablony" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Adresáře:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Soubory:" #: src/GMImportDialog.cpp:499 #: src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Synchronizovat" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Synchronizace" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "Importovat nové skladby\tImportuje soubory, které nejsou v databázi." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Odstranit skladby, které byly smazány z disku" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Aktualizovat existující skladby:" #: src/GMImportDialog.cpp:508 msgid "Modified since last import\tOnly reread the tag when the file has been modified." msgstr "Upravené od posledního importu\tJenom znovu načte značky, jestliže byl soubor změněn." #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Vše\tVždy číst všechny značky" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Odstranit skladby nalezené ve složce z databáze" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Skladba" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Nastavení analýzy" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Analyzovat z:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Značka" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Oba" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Výchozí hodnota:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Nastavit číslo skladby založené na pořadí skenování." #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - název %A - jméno alba\n" "%P - jméno interpreta alba\n" "%p - jméno interpreta skladby\n" "%N - číslo skladby %G - žánr" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Nahradit podtržení mezerami" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Import" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Nemohu inicializovat audio ovladač." #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Neznámý hostitel." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Neznámé zařízení" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Síť není dostupná." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Audio výstup nedostupný." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Připojení odmítnuto." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Soubor nenalezen." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Zdroje nejsou dostupné. Zkontrolujte práva" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Chyba čtení" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Chyba při načtení knihovny/zásuvného modulu" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Varování" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Bezpečnostní varování" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Neznámá chyba" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Chyba" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Nemohu vytvořit adresář %s\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Z nějakého důvodu je FOX knihovna byla zkompilována bez podpory PNG.\n" "Pro zobrazení ikon, Goggles Music Manager potřebuje podporu\n" "PNG ve FOX knihovně. Při vlastní kompilaci FOX, toto\n" "nastane, když nejsou nainstalovány hlavičkové soubory libpng v systému." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "Session bus není dostupný. Všechny funkce vyžadující dbus jsou zakázané." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "Nastala chyba DBus. Všechny funkce vyžadující sessionbus jsou zakázané." #: src/GMPlayerManager.cpp:644 msgid "Session Bus not available. All features requiring sessionbus are disabled." msgstr "Session bus není dostupný. Všechny funkce vyžadující sessionbus jsou zakázané." #: src/GMPlayerManager.cpp:719 #: src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Chyba audio zařízení" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Chyba Last.FM" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Chyba přehrávání" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" "%s\n" "%s (%d)" #: src/GMPlayListSource.cpp:99 #: src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 #: src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Odstranit...\tDel\tOdstraní skladbu(y) ze seznamu skladeb." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Upravit..." #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "Import…" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Odstranit seznam skladeb" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Odstranit skladby žánru ze seznamu skladeb?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Odstranit skladby interpreta ze seznamu skladeb?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Odstranit skladby z alba ze seznamu skladeb?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Odstranit skladbu(y) ze seznamu skladeb?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Odstranit skladby z knihovny" #: src/GMPlayListSource.cpp:406 #: src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Upravit seznam skladeb" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Změnit jméno seznamu skladeb" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Smazat seznam skladeb?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Jste si jistý, že chcete smazat seznam skladeb?" #: src/GMPlayListSource.cpp:432 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Ano" #: src/GMPlayListSource.cpp:432 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Ne" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Volby" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Obecné" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Volby seřazení" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Ignorovat první slova" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Obaly alb" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "Zobrazit obal přehrávané skladby\tZobrazí obal přehrávané skladby" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "Zobrazit obaly v prohlížeči alb\tZobrazí obaly v prohlížeči alb" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "System Tray" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Zobrazit tray ikonu\tZobrazí tray ikonu v system tray." #: src/GMPreferencesDialog.cpp:307 msgid "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "Zobrazit upozornění na změnu skladby\tInformuje upozorňovacího démona na změnu skaldby." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "Tato verze Goggles Music Manager\n" "nepodporuje Last-FM. Prosím upgradujte\n" "na novější verzi GMM." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "Služba:" #: src/GMPreferencesDialog.cpp:338 msgid "&Sign up…" msgstr "&Přihlásit se …" #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Uživatelské jméno:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Heslo:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "Scrobble" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Okno" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Okno" #: src/GMPreferencesDialog.cpp:365 msgid "Close button minimizes to tray" msgstr "Tlačítko zavřít minimalizuje do tray" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Zobrazit stavový řádek" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Zobrazit ikony v prohlížeči skladeb" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Zobrazit přehrávanou skladbu v titulkovém pruhu" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Ovládání přehrávače" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Umístění:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Nahoře" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Dole" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "Formát názvu:" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Styl:" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Zobrazit popisy" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Velké ikony" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "V&zhled" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Barvy" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "fg\tBarva textu" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "bg\tBarva pozadí " #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt bg\tAlternativní barva pozadí" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normální\tBarva normálního textu" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Základní\tZákladní barva" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Vybraná\tBarva vybraného textu" #: src/GMPreferencesDialog.cpp:433 msgid "Menu\tMenu Base Color" msgstr "Menu\tZákladní barva menu" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menu\tBarva menu" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Okraj\tBarva okraje" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Tooltip\tBarva tooltip" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Zvýrazněné\tBarva zvýraznění" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Stín\tBarva stínu" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Přehrávané\tBarva přehrávané skladby" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "Tray\tBarva pozadí tray" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Přednastaveno:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "Font & Ikony" #: src/GMPreferencesDialog.cpp:487 msgid "Default Font" msgstr "Výchozí font" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Změnit..." #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Ikony" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Audio" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Engine" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Audio ovladač:" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Zavřít audio zařízení při pozastavení." #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Vypnout engine přehrávání při zastavení." #: src/GMPreferencesDialog.cpp:529 msgid "Turn on playback engine on startup.\tFor faster startup, playback engine is normally started when first track is played.\tFor faster startup, playback engine is normally started when first track is played." msgstr "Zapnout engine přehrávání při startu.\tPro rychlejší spuštění, engine přehrávání se normálně při přehrávání první skaldby.\tPro rychlejší spuštění, engine přehrávání se normálně při přehrávání první skaldby." #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Přehrávání" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Zisk přehrávání:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "Vypnout" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Přehrávání bez mezer" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Normalizace hlasitosti" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "Nemohu otevřít požadovaný audio ovladač: %s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Aktuální" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Uživatelský" #: src/GMPreferencesDialog.cpp:769 #: src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 #: src/GMWindow.cpp:1140 #: src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Nemohu spustit webový prohlížeč" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Vybrat font" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Následující" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "Pře&dchozí" #: src/GMRemote.cpp:297 #: src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Přehrát" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Zastavit" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Zobrazit prohlížeč" #: src/GMRemote.cpp:301 #: src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Ukončit" #: src/GMRemote.cpp:385 msgid "\tShow Browser\tShow Browser" msgstr "\tZobrazit prohlížeč\tZobrazí prohlížeč" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tSpustit přehrávání\tSpustí přehrávání" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tZastavit přehrávání\tZastaví přehrávání" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tPřehrát předchozí skladbu\tPřehraje předchozí skladbu." #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tPřehrát následující skladbu\tPřehraje následující skladbu." #: src/GMRemote.cpp:397 #: src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tNastavit hlasitost\tNastaví hlasitost" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Nemohu otevřít databázi" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "Chyba databáze: Nemohu získat všechna jména souborů." #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "Nemohu aktualizovat skladbu" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Nemohu vložit skladbu do databáze" #: src/GMSearch.cpp:505 #: src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Fatální chyba" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Kontaktujte podporu, jestliže chyba přetrvává." #: src/GMSearch.cpp:534 #: src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Aktualizace databáze..." #: src/GMSearch.cpp:537 #: src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Prosím vyčkejte. Může to zabrat nějaký čas." #: src/GMSearch.cpp:555 #: src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Nové skladby:" #: src/GMSearch.cpp:561 #: src/GMSearch.cpp:643 msgid "File:" msgstr "Soubor:" #: src/GMSearch.cpp:594 #: src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Import souborů..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "&Zastavit import" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "Zdroje\tStisknout pro změnu řazení\tStisknutí změní řazení" #: src/GMSourceView.cpp:245 #: src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Nový seznam skladeb...\t\tVytvoří nový seznam skladeb" #: src/GMSourceView.cpp:246 #: src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "Načíst seznam skladeb...\t\tNačte existující seznam skladeb" #: src/GMSourceView.cpp:247 #: src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Nová rádiová stanice...\t\tVytvoří novou stanici" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Stanice" #: src/GMStreamSource.cpp:112 #: src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Nová stanice…\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Upravit...\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Odstranit\t\tOdstraní." #: src/GMStreamSource.cpp:165 #: src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Nová internetová stanice" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Zadejte url a popis nové stanice" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "Vy&tvořit" #: src/GMStreamSource.cpp:173 #: src/GMStreamSource.cpp:211 msgid "Location" msgstr "Adresa" #: src/GMStreamSource.cpp:175 #: src/GMStreamSource.cpp:214 msgid "Description" msgstr "Popis" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Bez názvu" #: src/GMStreamSource.cpp:202 #: src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Upravit internetovou stanici" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Aktualizace url a popisu stanice" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Odstranit internetovou rádiovou stanici(e)?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Odstranit internetovou rádiovou stanici(e) z knihovny?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Nemohu odstranit stanici z knihovny." #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" "Nekompatibilní (budoucí) verze databáze.\n" "Obvykle nastane při snížení na starší verzi GMM\n" "Stiskněte OK pro pokračování a vynulování databáze (všechny informace budou ztraceny!).\n" "Stiskněte Zrušit pro ukončení a ponechání databáze jak je." #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmm" msgstr "" "Goggles Music Manager nemohl otevřít databázi.\n" "Databáze může být poškozená. Odstraňte ~/.goggles/goggles.db a zkuste znovu.\n" "Jestliže chyba přetrvává, reportujte na http://code.google.com/p/gogglesmm" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tZavřít filtr\tZavře filtr" #: src/GMTrackView.cpp:246 msgid "&Find" msgstr "&Najít" #: src/GMTrackView.cpp:252 msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "Tagy\tStisknout pro změnu řazení\tStisknutí změní řazení" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "Interpreti\tStisknout pro změnu řazení\tStisknutí změní řazení" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "Alba\tStisknout pro změnu řazení\tStisknutí změní řazení" #: src/GMTrackView.cpp:282 #: src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Konfigurovat sloupce…" #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Prohlížeč" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Náhodně\tCtrl-R" #: src/GMTrackView.cpp:294 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Obráceně" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Všechny %d žánry" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Všechny žánry" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Všichni %d interpreti" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Všechna %d alba" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "Podle %s" #: src/GMTrackView.cpp:1586 #: src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Seřadit podle roku vydání alba" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Sloupce\t\tZmění viditelné sloupce." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "&Seřazení\t\tZmění seřazení." #: src/GMTrayIcon.cpp:302 #: src/GMWindow.cpp:841 #: src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 #: src/GMWindow.cpp:954 msgid "Play" msgstr "Přehrát" #: src/GMTrayIcon.cpp:303 #: src/GMWindow.cpp:843 msgid "Stop" msgstr "Zastavit" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Předchozí skladba" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Následující skladba" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Přehrát\tSpustit přehrávání\tSpustí přehrávání" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Pozastavit\tPozastavit\tPozastaví přehrávání" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Zastavit\tZastavit přehrávání\tZastaví přehrávání" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Předchozí\tPřehrát předchozí skladbu\tPřehraje předchozí skladbu." #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Následující\tPřehrát následující skladbu\tPřehraje následující skladbu." #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Hudba" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "Importovat složku...\tCtrl-O\tImportuje hudbu ze složky do knihovny" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "Synchronizovat složku...\t\tSynchronizuje složku s hudbou v knihovně" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "Přehrát soubor nebo přenos...\t\tPřehraje soubor nebo přenos" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "&Ukončit\tCtrl-Q\tUkončí aplikaci." #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "&Editovat" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Kopírovat\tCtrl-C\tKopíruje vybrané skladby" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "&Vyjmout\tCtrl-X\tVyjme vybrané skladby" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "V&ložit\tCtrl-V\tVloží výběr ze schránky" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Najít\tCtrl-F\tZobrazí filtr vyhledávání." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Nastavení..." #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Pohled" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "&Prohlížeč\tCtrl-B\tZobrazí prohlížeč žánrů interpretů a alb." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "Zobrazit žán&ry\tCtrl-G\tZobrazí prohlížeč žánrů." #: src/GMWindow.cpp:287 #: src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Zobrazit &zdroje\tCtrl-S\tZobrazí prohlížeč zdrojů" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Zobrazit přes celou obrazovku\tF12\tPřepne mód celé obrazovky." #: src/GMWindow.cpp:296 msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Zobrazit mini přehrávač\tCtrl-M\tPřepne mini přehrávač." #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Seřadit" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "&Přeskočit na aktuální skladbu\tCtrl-J\tZobrazí aktuálně přehrávanou skladbu." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Ovládání" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Přehrát\tCtrl-P\tSpustí přehrávání." #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Zastavit\tCtrl-\\\tZastaví přehrávání." #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Předchozí skladba\tCtrl-[\tPřehraje předchozí skladbu." #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Následující skladba\tCtrl-]\tPřehraje následující skladbu." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Opakovat\tCtrl-,\tOpakuje aktuální sladbu." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Opakovat skladbu\tCtrl-.\tOpakuje aktuální skladbu." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Opakovat všechny skladby\tCtrl-/\tOpakuje všechny skladby." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Opakovat A-B\tCtrl-T\tOpakuje část skladeb." #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Náhodně\tAlt-R\tPřehrává skladby v náhodném pořadí." #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Ekvalizér\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Čas uspání\t\tNastaví čas uspání." #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Nápověda" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Domovská stránka" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "&Reportovat problém..." #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "&Přihlásit se do last.fm…" #: src/GMWindow.cpp:328 msgid "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "&Připojit GMM na last.fm...\t\tPřipojí skupinu Goggles Music Manager na last.fm..." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "&O programu..." #: src/GMWindow.cpp:842 #: src/GMWindow.cpp:940 msgid "Pause" msgstr "Pozastavit" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Předchozí" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Následující" #: src/GMWindow.cpp:920 #: src/GMWindow.cpp:949 #: src/GMWindow.cpp:955 msgid "Start playback." msgstr "Spustí přehrávání." #: src/GMWindow.cpp:926 #: src/GMWindow.cpp:927 msgid "Start playback" msgstr "Spustí přehrávání" #: src/GMWindow.cpp:934 #: src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Pozastaví přehrávání." #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "Pozastaví přehrávání" #: src/GMWindow.cpp:1052 #: src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Opakovat A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Opakovat A" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "Přehrát soubor nebo přenos" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "Zadejte soubor nebo url k přehrání:" #: src/GMWindow.cpp:1206 msgid "…" msgstr "…" #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "Vybrat soubor" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Čas uspání" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Nastavit čas uspání" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Zastavit přehrávání za daný čas" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Spustit časovač" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Uspat za" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "hodin a" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "minut." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Hudební knihovna" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Internetové rádio" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Ukončit" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "&Přeskočit" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Přeskočit &vše" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Neukládat" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tVybrat barvu" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tOdstín, sytost, hodnota" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tČervená, zelená, modrá" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "Če&rvená:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Zelená:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Modrá:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Odstín:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Sytost:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Hodnota:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tAzurová, fialová, žlutá" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Azurová:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Fialová:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Žlutá:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tPodle jména" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Vytvořit nový adresář" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Již existuje" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Nemohu vytvořit" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Kopírovat soubor" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Chyba kopírování souboru" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Přesunutí souboru" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Chyba přesunu souboru" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Odkázat soubor" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Chyba odkazu soubor" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Mazání souboru" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Chyba mazání souboru" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "O úroveň výš" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Domovský adresář" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Pracovní adresář" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Seřazení" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Ignorovat velikost" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Skryté soubory" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Záložky" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Nastavit záložky" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Vyčistit záložky" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Nový adresář..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Kopírovat..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Přesunout..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Odkazovat..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Smazat..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Datum úpravy" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Uživatel" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Skupina" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Atributy" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Odkaz" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Vytvořit nový adresář:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "Soubor nebo adresář %s již existuje.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Nemohu vytvořit adresář %s.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Kopírovat soubor z:\n" "\n" "%s\n" "\n" "do: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Nemohu kopírovat soubor:\n" "\n" "%s do: %s\n" "\n" "Pokračovat?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Přesunout soubor z:\n" "\n" "%s\n" "\n" "do: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Nemohu přesunout soubor:\n" "\n" "%s do: %s\n" "\n" "Pokračovat?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Linkovat soubor z:\n" "\n" "%s\n" "\n" "do: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Nemohu linkovat soubor:\n" "\n" "%s do: %s\n" "\n" "Pokračovat?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Mazání souborů" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Jste si jistý smazáním souboru:\n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "Nemohu smazat soubor:\n" "\n" "%s\n" "\n" "Pokračovat?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Vybrat vše" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Seřadit podle" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Náhled" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Malé ikony" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Velké ikony" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Detaily" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Řádky" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Sloupce" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Náhledové obrázky" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Normální obrázky" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Střední obrázky" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Obří obrázky" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "&Nahradit" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Na&hradit vše" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "H&ledat:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Nahradit &s:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "Pře&sně" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Ignorovat velikost" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "Vý&raz" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Zpětně" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Hledat" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Připraven." #~ msgid "Old Name" #~ msgstr "Staré jméno" #~ msgid "New Name" #~ msgstr "Nové jméno" #~ msgid "Pitch:" #~ msgstr "Rozteč:" #~ msgid "Any" #~ msgstr "Vše" #~ msgid "Fixed" #~ msgstr "Fixní" #~ msgid "Variable" #~ msgstr "Variabilní" #, fuzzy #~ msgid " Type:" #~ msgstr "Typ" #, fuzzy #~ msgid "Scalable" #~ msgstr "S měřítkem:" #, fuzzy #~ msgid "Size:" #~ msgstr "Velikost" #, fuzzy #~ msgid "Family:" #~ msgstr "&Rodina:" #~ msgid "Always Show Remote" #~ msgstr "Vždy zobrazit vzdálené" #~ msgid "Source\tActive Source Color" #~ msgstr "Zdroj\tBarva aktivního zdroje" #~ msgid "About" #~ msgstr "O programu" #~ msgid "" #~ "An incompatible version of SQLite (%s) is being used.\n" #~ "Goggles Music Manager requires at least SQLite 3.3.8.\n" #~ "Please upgrade your SQLite installation." #~ msgstr "" #~ "Používána nekompatabilní verze SQLite (%s).\n" #~ "Goggles Music Manager vyžaduje nejméně SQLite 3.3.8.\n" #~ "Prosím aktualizujte SQLite." #~ msgid "" #~ "This version of SQLite (%s) is broken.\n" #~ "Please upgrade your SQLite installation to at least 3.6.3." #~ msgstr "" #~ "Verze SQLite (%s) je poškozená.\n" #~ "Prosím aktualizujte SQLite na nejméně 3.6.3." #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "&Připojit GMM na last.fm…\tPřipojit skupinu Goggles Music Manager na last." #~ "fm…\tPřipojí skupinu Goggles Music Manager na last.fm…" #~ msgid "Font" #~ msgstr "Font" #~ msgid "Theme Directory:" #~ msgstr "Adresář s tématem:" #~ msgid "Select Theme Directory" #~ msgstr "Vybrat adresář z tématem" #~ msgid "thin" #~ msgstr "tenké" #~ msgid "normal" #~ msgstr "normální" #~ msgid "bold" #~ msgstr "tučné" #~ msgid "regular" #~ msgstr "normální" #~ msgid "&Weight:" #~ msgstr "&Tloušťka:" #~ msgid "&Style:" #~ msgstr "&Styl:" #~ msgid "Si&ze:" #~ msgstr "Ve&likost:" #~ msgid "Character Set:" #~ msgstr "Znaková sada:" #~ msgid "West European" #~ msgstr "Západoevropské" #~ msgid "East European" #~ msgstr "Východoevropské" #~ msgid "South European" #~ msgstr "Jihoevropské" #~ msgid "North European" #~ msgstr "Severoevropské" #~ msgid "Cyrillic" #~ msgstr "Cyrilice" #~ msgid "Arabic" #~ msgstr "Arabské" #~ msgid "Greek" #~ msgstr "Řecké" #~ msgid "Hebrew" #~ msgstr "Hebrejské" #~ msgid "Turkish" #~ msgstr "Turecké" #~ msgid "Nordic" #~ msgstr "Skandinávský" #~ msgid "Thai" #~ msgstr "Thajské" #~ msgid "Baltic" #~ msgstr "Baltské" #~ msgid "Celtic" #~ msgstr "Keltské" #~ msgid "Russian" #~ msgstr "Ruské" #~ msgid "Central European (cp1250)" #~ msgstr "Středoevropské (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Ruské (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Latin1 (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Řecké (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Turecké (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Hebrejské (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Arabské (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Baltské (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Vietnamské (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Thajské (cp874)" #~ msgid "UNICODE" #~ msgstr "UNICODE" #~ msgid "Set Width:" #~ msgstr "Nastavit šířku:" #~ msgid "All Fonts:" #~ msgstr "Všechny fonty:" #~ msgid "Preview:" #~ msgstr "Náhled:" #~ msgid "Import Playlist…\t\tImport a existing playlist" #~ msgstr "Načíst seznam skladeb...\t\tNačte existující seznam skladeb" #~ msgid "Import Files?" #~ msgstr "Importovat soubory?" #~ msgid "" #~ "Would you like import the pasted files and/or directories into the Music " #~ "Library?" #~ msgstr "Chcete importovat vložené soubory a/nebo adresáře do knihovny?" #~ msgid "" #~ "%s\n" #~ "by: %s\n" #~ "from: %s" #~ msgstr "" #~ "%s\n" #~ "od: %s\n" #~ "z: %s" #~ msgid "Now Playing" #~ msgstr "Nyní hraje" #~ msgid "Open URL…\t\tOpen Stream or File" #~ msgstr "Otevřít URL...\t\tOtevře proud nebo soubor" #~ msgid "Open MRL" #~ msgstr "Otevřít MRL" gogglesmm-0.12.7/po/gogglesmm.pot0000644000175000001440000013656211524673460015455 0ustar sxjusers# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.0\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "" #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "" #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "" #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "" #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "" #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "" #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "" #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "" #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "" #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "" #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 msgid "&Properties" msgstr "" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "" #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "" #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "" #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "" #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "" #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "" #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "" #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "" #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "" #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "" #: src/GMFontDialog.cpp:209 msgid "Ultra Condensed" msgstr "" #: src/GMFontDialog.cpp:210 msgid "Extra Condensed" msgstr "" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "" #: src/GMFontDialog.cpp:212 msgid "Semi Condensed" msgstr "" #: src/GMFontDialog.cpp:214 msgid "Semi Expanded" msgstr "" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "" #: src/GMFontDialog.cpp:216 msgid "Extra Expanded" msgstr "" #: src/GMFontDialog.cpp:217 msgid "Ultra Expanded" msgstr "" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 msgid "Extra Light" msgstr "" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 msgid "Light" msgstr "" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 msgid "Medium" msgstr "" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 msgid "Demibold" msgstr "" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 msgid "Extra Bold" msgstr "" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 msgid "Heavy" msgstr "" #: src/GMFontDialog.cpp:239 msgid "Reverse Oblique" msgstr "" #: src/GMFontDialog.cpp:240 msgid "Reverse Italic" msgstr "" #: src/GMFontDialog.cpp:242 msgid "Italic" msgstr "" #: src/GMFontDialog.cpp:243 msgid "Oblique" msgstr "" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "" #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "" #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "" #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "" #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "" #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "" #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "" #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "" #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "" #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "" #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "" #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "" #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "" #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "" #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "" #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "" #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "" #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "" #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "" #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "" #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "" #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "" #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "" #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "" #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 msgid "&Sign up…" msgstr "" #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "" #: src/GMPreferencesDialog.cpp:365 msgid "Close button minimizes to tray" msgstr "" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:433 msgid "Menu\tMenu Base Color" msgstr "" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 msgid "Default Font" msgstr "" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "" #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "" #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "" #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "" #: src/GMRemote.cpp:385 msgid "\tShow Browser\tShow Browser" msgstr "" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "" #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "" #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "" #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "" #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "" #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "" #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "" #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "" #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "" #: src/GMTrackView.cpp:246 msgid "&Find" msgstr "" #: src/GMTrackView.cpp:252 msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "" #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "" #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "" #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "" #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "" #: src/GMWindow.cpp:255 msgid "&Music" msgstr "" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "" #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "" #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "" #: src/GMWindow.cpp:282 msgid "&View" msgstr "" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "" #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "" #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "" #: src/GMWindow.cpp:296 msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "" #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "" #: src/GMWindow.cpp:306 msgid "&Control" msgstr "" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "" #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "" #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "" #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "" #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "" #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "" #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "" #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "" #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "" #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "" #: src/GMWindow.cpp:323 msgid "&Help" msgstr "" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "" #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "" #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" #: src/GMWindow.cpp:330 msgid "&About…" msgstr "" #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "" #: src/GMWindow.cpp:845 msgid "Next" msgstr "" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "" #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 msgid "Start playback" msgstr "" #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "" #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "" #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "" #: src/GMWindow.cpp:1206 msgid "…" msgstr "" #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "" #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "" gogglesmm-0.12.7/po/de.po0000644000175000001440000022015311524673460013666 0ustar sxjusers# German translations for musicmanager package. # Copyright (C) 2009 Sander Jansen # This file is distributed under the same license as the musicmanager package. # Hendrik Rittich , 2009. # msgid "" msgstr "" "Project-Id-Version: gogglesmm 0.10.0\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2009-07-06 09:41-0600\n" "Last-Translator: Sander Jansen \n" "Language-Team: German\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/GMAbout.cpp:136 src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "S&chließen" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Spalten konfigurieren" #: src/GMColumnDialog.cpp:207 ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "Über&nehmen" #: src/GMColumnDialog.cpp:208 src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 src/GMStreamSource.cpp:169 src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 src/GMWindow.cpp:1198 src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "A&bbrechen" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Bitte wählen Sie die Reihenfolge, in der die\n" "Informationen in der Titelliste erscheinen sollen." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Nach oben verschieben" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Nach unten verschieben" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Ungültige Vorlage" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be " "specified.\n" "Please fix the filename template in the preference panel." msgstr "" "Die eingegebene Vorlage ist leider ungültig. Der Name des Titels %%T muss " "angegeben werden.\n" "Bitte korrigieren Sie die Vorlage für Dateinamen im Einstellungs-Dialog." #: src/GMDatabaseSource.cpp:72 src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Datenbank-Fehler" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Oh je. Ein Datenbank-Fehler" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Keine Änderungen" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Für die Dateinamen war keine Änderung nötig" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Audio-Dateien umbenennen?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "Die Audio-Dateien werden umbenannt…" #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "Die folgenden Audio-Dateien werden umbenannt" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "Um&benennen" #: src/GMDatabaseSource.cpp:121 src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Umbenennen der Datei nicht möglich" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "Konnte die Datei nicht umbenennen:\n" "%s\n" "\n" "in:%s\n" "\n" "Trotzdem fortfahren?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "Umbenennen der Datei nicht möglich:\n" "%s\n" "\n" "in:%s" #: src/GMDatabaseSource.cpp:160 src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Vorlage für Dateinamen" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "Die Vorlage darf einen absoluten oder relativen Pfad enthalten, \n" "Umgebungsvariablen und ~. Relative Pfadangaben beziehen sich auf den\n" "ursprünglichen Ort der Datei. Die Datei-Erweiterung wird automatisch\n" "ergänzt. Die folgenden Macros dürfen benutzt werden:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - Titelname %A - Albumname\n" "%P - Künstlername des Albums %p - Künstlername des Titels\n" "%y - Jahr %d - Disc-Nummer\n" "%N - Titelnummer (2 stellig) %n - Titelnummer\n" "%G - Genre" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" #: src/GMDatabaseSource.cpp:195 src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Vorlage:" #: src/GMDatabaseSource.cpp:199 src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Kodierung:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Ausnahmen:" #: src/GMDatabaseSource.cpp:209 src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Optionen:" #: src/GMDatabaseSource.cpp:210 src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Ersetze Leerzeichen durch Unterstriche" #: src/GMDatabaseSource.cpp:212 src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Kleinschreibung" #: src/GMDatabaseSource.cpp:214 src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Klein geschriebene Datei-Erweiterung" #: src/GMDatabaseSource.cpp:341 src/GMStreamSource.cpp:63 msgid "No." msgstr "Nr." #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Warteschlange" #: src/GMDatabaseSource.cpp:343 src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Titelname" #: src/GMDatabaseSource.cpp:344 src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Künstler" #: src/GMDatabaseSource.cpp:345 src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Künstlername des Albums" #: src/GMDatabaseSource.cpp:346 src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 src/GMTrackView.cpp:240 msgid "Album" msgstr "Album" #: src/GMDatabaseSource.cpp:347 src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Disc" #: src/GMDatabaseSource.cpp:348 src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 src/GMTrackView.cpp:241 msgid "Genre" msgstr "Genre" #: src/GMDatabaseSource.cpp:349 src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Jahr" #: src/GMDatabaseSource.cpp:350 ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Zeit" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Löschen…\tDel\tDas Genre aus der Bibliothek löschen." #: src/GMDatabaseSource.cpp:496 src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Kopieren\tCtrl-C\tKopiere die zugehörigen Titel in die Zwischenablage" #: src/GMDatabaseSource.cpp:499 src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Löschen…\tDel\tLösche die zugehörigen Titel aus der Bibliothek" #: src/GMDatabaseSource.cpp:513 src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Bearbeiten…\tF2\tBearbeite die Titel-Informationen." #: src/GMDatabaseSource.cpp:514 src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Kopieren\tCtrl-C\tKopiere die/den Titel in die Zwischenablage." #: src/GMDatabaseSource.cpp:518 src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Löschen…\tDel\tLösche die/den Titel aus der Bibliothek." #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Neue Wiedergabeliste…\t\tErstelle eine neue Wiedergabeliste" #: src/GMDatabaseSource.cpp:539 src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Exportieren…" #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Informationen…\t\tBibliotheksstatistik" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "Alle Titel entfernen\t\tEntferne alle Titel aus der Bibliothek" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Bearbeite die Titel-Informationen" #: src/GMDatabaseSource.cpp:1275 src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Speichern" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "" #: src/GMDatabaseSource.cpp:1320 #, fuzzy msgid "&Properties" msgstr "Einstellungen" #: src/GMDatabaseSource.cpp:1325 src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Dateiname" #: src/GMDatabaseSource.cpp:1329 ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Typ" #: src/GMDatabaseSource.cpp:1333 ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Größe" #: src/GMDatabaseSource.cpp:1341 src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Bitrate" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Sampelrate" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Kanäle" #: src/GMDatabaseSource.cpp:1358 src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Titel" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "\tKünstler aufteilen" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "\tKünstler teilen" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "Automatische Titelnummer. Erste Nummer:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Aktualisiere den Tag in der Datei" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Dateiname aktualisieren" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Wähle Export-Vorlage…" #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Tags aktualisieren?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Keine Titel wurden aktualisiert.\n" "Möchten Sie immer noch die Tags für die ausgewählten Titel in die Datei " "schreiben?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Audio-Dateien entfernen?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Audio-Dateien werden entfernt..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Die folgenden Audio-Dateien werden entfernt" #: src/GMDatabaseSource.cpp:1703 src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Entfernen" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Exportiere die Hauptbibliothek" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Exportiere Wiedergabeliste" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Datei überschreiben?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "Die Datei existiert bereits. Möchten Sie sie überschreiben?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Genre exportieren" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Exportiere die Titel diesen Genres ins Zielverzeichnis." #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Künstler exportieren" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Exportiere die Titel dieses Künstlers ins Zielverzeichnis." #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Album exportieren" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Exportiere die Titel dieses Albums ins Zielverzeichnis." #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Titel exportieren" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Exportiere die Titel ins Zielverzeichnis" #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Exportieren" #: src/GMDatabaseSource.cpp:1853 src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Genre entfernen?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Entferne die Titel dieses Genres aus der Bibliothek." #: src/GMDatabaseSource.cpp:1858 src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Künstler entfernen?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Entferne die Titel dieses Künstlers aus der Bibliothek." #: src/GMDatabaseSource.cpp:1863 src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Album entfernen?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Entferne die Titel dieses Albums aus der Bibliothek." #: src/GMDatabaseSource.cpp:1868 src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Titel entfernen?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Die/Den Titel aus der Bibliothek entfernen?" #: src/GMDatabaseSource.cpp:1881 src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Entferne die Titel von der Festplatte" #: src/GMDatabaseSource.cpp:1895 src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Fehler in der Bibliothek" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "Das Genre konnte nicht aus der Bibliothek gelöscht werden." #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Der Künstler konnte nicht aus der Bibliothek gelöscht werden." #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Das Album konnte nicht aus der Bibliothek gelöscht werden." #: src/GMDatabaseSource.cpp:1907 src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "Der Titel konnte nicht aus der Bibliothek gelöscht werden." #: src/GMDatabaseSource.cpp:2117 src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Erstelle Wiedergabeliste" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Geben Sie den Name der Wiedergabeliste ein" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "&Erstellen" #: src/GMDatabaseSource.cpp:2125 src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Name" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Neue Wiedergabeliste" #: src/GMDatabaseSource.cpp:2178 src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Musikbibliothek leeren?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Alle Titel aus der Musikbibliothek entfernen?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Entferne Alle" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Wiedergabelisten behalten" #: src/GMDatabaseSource.cpp:2212 src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Musikbibliothek-Informationen" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "Ihre Musiksammlung besteht aus…" #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Titel:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Künstler:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Alben:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Zeit insgesamt:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Equalizer" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Equalizer:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tSpeichern" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tZurücksetzen" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tEntfernen" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Vorverstärker" #: src/GMEQDialog.cpp:244 src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Deaktiviert" #: src/GMEQDialog.cpp:247 src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Manuell" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Voreinstellung löschen" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Sind Sie sicher, dass Sie die Einstellung %s löschen wollen?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Name der Voreinstellung" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Bitte geben Sie den Namen der Voreinstellung ein:" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Voreinstellung überschreiben" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "Die Einstellung %s existiert bereits. Möchten Sie sie überschreiben?" #: src/GMFontDialog.cpp:209 #, fuzzy msgid "Ultra Condensed" msgstr "Wahnsinnig dünn" #: src/GMFontDialog.cpp:210 #, fuzzy msgid "Extra Condensed" msgstr "Besonders dünn" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "dünn" #: src/GMFontDialog.cpp:212 #, fuzzy msgid "Semi Condensed" msgstr "Halbdünn" #: src/GMFontDialog.cpp:214 #, fuzzy msgid "Semi Expanded" msgstr "Halbbreit" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Breit" #: src/GMFontDialog.cpp:216 #, fuzzy msgid "Extra Expanded" msgstr "Besonders Breit" #: src/GMFontDialog.cpp:217 #, fuzzy msgid "Ultra Expanded" msgstr "Wahnsinnig Breit" #: src/GMFontDialog.cpp:224 src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "" #: src/GMFontDialog.cpp:225 src/GMPreferencesDialog.cpp:1224 #, fuzzy msgid "Extra Light" msgstr "besonders dünn" #: src/GMFontDialog.cpp:226 src/GMPreferencesDialog.cpp:1225 #, fuzzy msgid "Light" msgstr "leicht" #: src/GMFontDialog.cpp:228 src/GMPreferencesDialog.cpp:1227 #, fuzzy msgid "Medium" msgstr "mittel" #: src/GMFontDialog.cpp:229 src/GMPreferencesDialog.cpp:1228 #, fuzzy msgid "Demibold" msgstr "halbfett" #: src/GMFontDialog.cpp:230 src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "" #: src/GMFontDialog.cpp:231 src/GMPreferencesDialog.cpp:1230 #, fuzzy msgid "Extra Bold" msgstr "besonders fett" #: src/GMFontDialog.cpp:232 src/GMPreferencesDialog.cpp:1231 #, fuzzy msgid "Heavy" msgstr "sehr fett" #: src/GMFontDialog.cpp:239 #, fuzzy msgid "Reverse Oblique" msgstr "entgegengesetzt schief" #: src/GMFontDialog.cpp:240 #, fuzzy msgid "Reverse Italic" msgstr "entgegengesetzt kursiv" #: src/GMFontDialog.cpp:242 #, fuzzy msgid "Italic" msgstr "kursiv" #: src/GMFontDialog.cpp:243 #, fuzzy msgid "Oblique" msgstr "schief" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normal" #: src/GMImportDialog.cpp:91 ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "Ver&zeichnis" #: src/GMImportDialog.cpp:166 ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "&Dateiname:" #: src/GMImportDialog.cpp:168 ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "Dateif&ilter:" #: src/GMImportDialog.cpp:174 ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Schreibgeschützt" #: src/GMImportDialog.cpp:179 src/GMSearch.cpp:565 src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Verzeichnis:" #: src/GMImportDialog.cpp:186 ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "" "Le&sezeichen erstellen\t\tLege ein Lesezeichen ins aktuelle Verzeichnis." #: src/GMImportDialog.cpp:187 ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "Lesezeichen leeren\t\tEntferne alle Lesezeichen." #: src/GMImportDialog.cpp:203 ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tEine Ebene nach oben\tWechsele in ein höheres Verzeichnis." #: src/GMImportDialog.cpp:204 ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tZum Heimverzeichnis\tZurück ins Heimverzeichnis." #: src/GMImportDialog.cpp:205 ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tZum Arbeitsverzeichnis\tZurück zum Arbeitsverzeichnis." #: src/GMImportDialog.cpp:206 ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tLesezeichen\tZu einem Lesezeichen wechseln." #: src/GMImportDialog.cpp:209 ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tNeues Verzeichnis erstellen\tErstelle ein neues Verzeichnis." #: src/GMImportDialog.cpp:210 ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tListenansicht\tDas Verzeichnis mit kleinen Symbolen anzeigen." #: src/GMImportDialog.cpp:211 ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tSymbolansicht\tDas Verzeichnis mit großen Symbolen anzeigen." #: src/GMImportDialog.cpp:212 ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tDetailansicht\tDas Verzeichnis detailiert anzeigen." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "" "\tVersteckte Dateien anzeigen\tZeige versteckte Dateien und Verzeichnisse an." #: src/GMImportDialog.cpp:213 ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "" "\tVerstecke versteckte Dateien\tZeige keine versteckten Dateien und " "Verzeichnisse an." #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Ordner synchronisieren" #: src/GMImportDialog.cpp:414 #, fuzzy msgid "Import Playlist" msgstr "Exportiere Wiedergabeliste" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Musik importieren" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Dateien" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Verzeichnis" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "" "Ausfiltern\tFiltere Verzeichnisse und/oder Dateien nach einem Muster aus" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Ordner:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Dateien:" #: src/GMImportDialog.cpp:499 src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Sync" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Sync Operation" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "" "Neue Titel imporieren\tTitel, die sich noch nicht in der Datenbank befinden, " "werden importiert." #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Entferne von der Festplatte gelösche Titel" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Aktualisiere die bestehenden Titel:" #: src/GMImportDialog.cpp:508 msgid "" "Modified since last import\tOnly reread the tag when the file has been " "modified." msgstr "Zuletzt geänderte Dateien\tLies nur tag aus geänderten Dateien" #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Alle\tLies alle Tags" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Entferne alle Titel in diesem Ordner aus der Datenbank" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "&Titel" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Einstellungen lesen" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Lies die Informationen aus:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Tag" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Beides" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Standardwert:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Wähle die Titelnummer auf Grund der Scannreihenfolge" #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - Titelname %A - Albumname\n" "%P - Künstlername des Albums %p - Künstlername des Titels \n" "%N - Titelnummer %G - Genre" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Ersetze Unterstriche durch Leerzeichen" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Importieren" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Der Audiotreiber konnte nicht geladen werden." #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Unbekannter host." #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Unbekanntes Gerät." #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Keine Verbindung zum Netzwerk." #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Die Audioausgabe ist nicht verfügbar." #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Verbindung abgewiesen." #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Datei wurde nicht gefunden." #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Kein Zugriff auf die Ressource. Überprüfen Sie die Berechtigungen." #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Lesefehler" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Fehler beim Laden einer Bibliothek/Plugins" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Warnung" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Sicherheitswarnung" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Unbekannter Fehler" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Fehler" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Das Verzeichnis %s kann nicht erstellt werden.\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Das FOX-Toolkit wurde ohne PNG-Unterstützung kompiliert.\n" "Diese wird allerdings benötigt, damit Goggles Music Manager alle\n" "Symbole anzeigen kann. Wenn Sie das FOX-Toolkit selber kompiliert\n" "haben, so waren die libpng Header-Dateien wahrscheinlich nicht auf\n" "Ihrem System vorhanden." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "" "Der Session-Bus wurde nicht gefunden. Alle Funktionen, die DBus benötigen " "stehen nicht zur Verfügung." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "" "DBus hat einen Fehler verursacht. Alle Funktionen, die DBus benötigen stehen " "nicht zur Verfügung." #: src/GMPlayerManager.cpp:644 msgid "" "Session Bus not available. All features requiring sessionbus are disabled." msgstr "" "Der Session-Bus wurde nicht gefunden. Alle Funktionen, die DBus benötigen " "stehen nicht zur Verfügung." #: src/GMPlayerManager.cpp:719 src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Audio-Gerät-Fehler" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Last.FM-Fehler" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Wiedergabe-Fehler" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" #: src/GMPlayListSource.cpp:99 src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Entfernen…\tDel\tEntferne die/den Titel aus der Wiedergabeliste." #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Bearbeiten…" #: src/GMPlayListSource.cpp:162 #, fuzzy msgid "Import…" msgstr "Exportieren…" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Entferne Wiedergabeliste" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Entferne die Titel dieses Genres aus der Wiedergabeliste?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Entferne die Titel dieses Künstlers aus der Wiedergabeliste?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Entferne die Titel dieses Albums aus der Wiedergabeliste?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Entferne die/den Titel aus der Wiedergabeliste?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Entferne Titel aus der Musikbibliothek" #: src/GMPlayListSource.cpp:406 src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Wiedergabeliste bearbeiten" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Wiedergabeliste umbenennen" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Wiedergabeliste löschen?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Sind Sie sicher, dass Sie diese Wiedergabeliste löschen wollen?" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Ja" #: src/GMPlayListSource.cpp:432 ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Nein" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Einstellungen" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Allgemein" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Sortierungsoptionen" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Führende Worte ignorieren" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Albencover" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "" "Albumcover des abzuspielenden Titels anzeigen\tAlbumcover des abzuspielenden " "Titels anzeigen" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "" "Albumcover im Albenbrowser anzeigen\tAlbumcover im Albenbrowser anzeigen" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "Systemleiste" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Systemleistensymbol anzeigen\tZeige ein Symbol in der Systemleiste an." #: src/GMPreferencesDialog.cpp:307 msgid "" "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "" "Bei Titelwechsel benachrichtigen\tInformiere in der Systemleiste über " "Titelwechsel." #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "Diese Version von Goggles Music Manager wird\n" "nicht von Last-FM unterstützt. Bitte aktualisieren\n" "Sie GMM." #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "" #: src/GMPreferencesDialog.cpp:338 #, fuzzy msgid "&Sign up…" msgstr "Bei last.fm &anmelden…" #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Benutzername:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Passwort:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Fenster" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Fenster" #: src/GMPreferencesDialog.cpp:365 #, fuzzy msgid "Close button minimizes to tray" msgstr "Schließen Knopf minimiert das Hauptfenster" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Zeige die Statusleiste" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Zeige Symbole im Titel-Browser" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Aktuellen Titel in der Titelleiste anzeigen" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Player-Steuerung" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Ort:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Oben" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Unten" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Stil:" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Beschriftungen anzeigen" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Große Symbole" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "&Aussehen" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Farben" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "fg\tVordergrundfarbe" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "bg\tHintergrundfarbe" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "alt bg\tAlternative Hintergrundfarbe" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normal\tNormale Textfarbe" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Basis\tBasisfarbe" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Ausgewählt\tFarbe von ausgewähltem Text" #: src/GMPreferencesDialog.cpp:433 #, fuzzy msgid "Menu\tMenu Base Color" msgstr "Menü\tFarbe des Menüs" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menü\tFarbe des Menüs" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Rahmen\tRahmenfarbe" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Kurzinfo\tFarbe von Kurzinfos" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Hilite\tFarbe von Markierungen" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Schatten\tFarbe von Schatten" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Spielend\tFarbe des aktuellen Titels" #: src/GMPreferencesDialog.cpp:463 #, fuzzy msgid "Tray\tTray Background Color" msgstr "bg\tHintergrundfarbe" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Voreinstellungen:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "" #: src/GMPreferencesDialog.cpp:487 #, fuzzy msgid "Default Font" msgstr "Standardwert:" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Ändern…" #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Symbole" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "&Audio" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Engine" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Audio-Treiber:" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Bei Pausen Audio-Gerät freigeben." #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Beim Stoppen die Wiedergabe-Engine abschalten." #: src/GMPreferencesDialog.cpp:529 msgid "" "Turn on playback engine on startup.\tFor faster startup, playback engine is " "normally started when first track is played.\tFor faster startup, playback " "engine is normally started when first track is played." msgstr "" "Starte die Wiedergabe-Engine beim Programmstart.\tUm einen schnelleren " "Programmstart zu ermöglichen wird die Wiedergabe-Engine erst gestartet, wenn " "der erste Titel wiedergegeben wird\tUm einen schnelleren Programmstart zu " "ermöglichen wird die Wiedergabe-Engine erst gestartet, wenn der erste Titel " "wiedergegeben wird" #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Wiedergabe" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Verstärkung:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "Aus" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Lückenlose Wiedergabe" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Lautstärke angleichen" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "Der angeforderte Audiotreiber konnte nicht geladen werden: %s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Aktuell" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Benutzerdefiniert" #: src/GMPreferencesDialog.cpp:769 src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 src/GMWindow.cpp:1140 src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Es konnte kein Webbrowser gestartet werden" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Wähle normale Schriftart" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "&Nächster" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "&Vorheriger" #: src/GMRemote.cpp:297 src/GMWindow.cpp:1197 msgid "&Play" msgstr "&Play" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "&Stopp" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Browser anzeigen" #: src/GMRemote.cpp:301 src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Beenden" #: src/GMRemote.cpp:385 #, fuzzy msgid "\tShow Browser\tShow Browser" msgstr "Browser anzeigen" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tWiedergabe starten\tWiedergabe starten" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tWiedergabe anhalten\tWiedergabe anhalten" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tVorherigen Titel wiedergeben\tVorherigen Titel wiedergeben." #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tNächsten Titel wiedergeben\tNächsten Titel wiedergeben." #: src/GMRemote.cpp:397 src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tLautstärke einstellen\tLautstärke einstellen" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Die Datenbank konnte leider nicht geöffnet werden" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "Datenbank-Fehler: Die Dateinamen konnten leider nicht gelesen werden." #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "Der Titel konnte nicht aktualisiert werden" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Der Titel konnte nicht in die Datenbank eingetragen werden" #: src/GMSearch.cpp:505 src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Schwerwiegender Fehler" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Bitte wenden Sie sich an den Support, falls dieser Fehler öfter auftritt." #: src/GMSearch.cpp:534 src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "Die Datenbank wird aktualisiert..." #: src/GMSearch.cpp:537 src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Bitte warten Sie einen Moment." #: src/GMSearch.cpp:555 src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Neue Titel:" #: src/GMSearch.cpp:561 src/GMSearch.cpp:643 msgid "File:" msgstr "Datei:" #: src/GMSearch.cpp:594 src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "Dateien werden importiert..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "Import &stoppen" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "" "Quellen\tKlicken, um die Reihenfolge zu ändern\tKlicken, um die Reihenfolge " "zu ändern" #: src/GMSourceView.cpp:245 src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Neue &Wiedergabeliste…\t\tErstelle eine neue Wiedergabeliste" #: src/GMSourceView.cpp:246 src/GMWindow.cpp:262 #, fuzzy msgid "Import Playlist…\t\tImport existing playlist" msgstr "Neue &Wiedergabeliste…\t\tErstelle eine neue Wiedergabeliste" #: src/GMSourceView.cpp:247 src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Neuer &Radiosender…\t\tTrage einen neuen Radiosender ein" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Sender" #: src/GMStreamSource.cpp:112 src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Neuer Radiosender\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Bearbeiten…\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Entfernen\t\tEntfernen" #: src/GMStreamSource.cpp:165 src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Neuer Internetradiosender" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Geben Sie die URL und eine Beschreibung des Senders ein" #: src/GMStreamSource.cpp:168 #, fuzzy msgid "C&reate" msgstr "&Erstellen" #: src/GMStreamSource.cpp:173 src/GMStreamSource.cpp:211 msgid "Location" msgstr "Ort" #: src/GMStreamSource.cpp:175 src/GMStreamSource.cpp:214 msgid "Description" msgstr "Beschreibung" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Unbenannt" #: src/GMStreamSource.cpp:202 src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Bearbeite Radiosender" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Aktualisiere die URL und Beschreibung des Senders" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Radiosender entfernen?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Radiosender aus der Bibliothek entfernen?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Der Sender konnte nicht aus der Bibliothek gelöscht werden." #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be " "lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" "Es wurde eine inkompatible (neuere) Version der Datenbank gefunden.\n" "Dieser Fehler tritt beim Verwenden einer älteren GMM Version auf.\n" "Drücken Sie OK um fortzufahren. Dabei wird die Datenbank zrückgesetzt und " "alle zuvor gespeicherten Informationen verworfen! \n" "Drücken Sie Abbrechen um die Datenbank unverändert zu lassen." #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to " "try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/" "p/gogglesmm" msgstr "" "Google Music Manager konnte die Datenbank nicht öffnen.\n" "Die Datenbank wurde möglicherweise beschädigt. Bitte entfernen Sie die\n" "Datei ~/.goggles/goggles.db und versuchen Sie es erneut.\n" "Sollte der Fehler weiterhin bestehen, senden Sie bitte einen\n" "Fehlerbericht auf http://code.google.com/p/gogglesmm ein." #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tFilter schließen\tFilter schließen" #: src/GMTrackView.cpp:246 #, fuzzy msgid "&Find" msgstr "Suchen" #: src/GMTrackView.cpp:252 #, fuzzy msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "" "Genres\tKlicken, um die Reihenfolge zu ändern\tKlicken, um die Reihenfolge " "zu ändern" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "" "Künstlername\tKlicken, um die Reihenfolge zu ändern\tKlicken, um die " "Reihenfolge zu ändern" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "" "Alben\tKlicken, um die Reihenfolge zu ändern\tKlicken, um die Reihenfolge zu " "ändern" #: src/GMTrackView.cpp:282 src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "Spalten &konfigurieren" #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Browser anzeigen" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Zufällige Wiedergabe\tCtrl-R" #: src/GMTrackView.cpp:294 ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Rückwärts" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Alle %d Genre" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Alle Genre" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Alle %d Künstler" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Alle %d Alben" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "Nach %s" #: src/GMTrackView.cpp:1586 src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Sortiere nach Erscheinungsjahr" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Spalten\t\tÄndere die Spalten." #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "&Sortierung\t\tSortierung ändern." #: src/GMTrayIcon.cpp:302 src/GMWindow.cpp:841 src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 src/GMWindow.cpp:954 msgid "Play" msgstr "Play" #: src/GMTrayIcon.cpp:303 src/GMWindow.cpp:843 msgid "Stop" msgstr "Stop" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Vorherigen Titel" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Nächsten Titel" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Play\tStarte die Wiedergabe\tStarte die Wiedergabe" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Pause\tPause\tDie Wiedergabe pausieren" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Stopp\tDie Wiedergabe anhalten\tDie Wiedergabe anhalten" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Vorherigen\tVorherigen Titel wiedergeben\tVorherigen Titel wiedergeben" #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Nächsten\tNächsten Titel wiedergeben\tNächsten Titel wiedergeben" #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Musik" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "" "Ordner &importieren…\tCtrl-O\tImportiere die Musik aus einem Ordner in die " "Bibliothek" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "" "Ordner &synchronisieren…\t\tSynchronisiere die Ordner mit der Bibliothek" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "B&eenden\tCtrl-Q\tBeende die Anwendung." #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "B&earbeiten" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Kopieren\tCtrl-C\tDie ausgewählten Titel kopieren" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "Auss&chneiden\tCtrl-X\tDie ausgewählten Titel ausschneiden" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "E&infügen\tCtrl-V\tAus der Zwischenablage einfügen" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Suchen…\tCtrl-F\tZeige Suchfilter." #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Einstellungen…" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Ansicht" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "&Browser anzeigen\tCtrl-B\tZeige den Künstler- und Alben-Browser." #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "&Genre anzeigen\tCtrl-G\tZeige den Genre-Browser." #: src/GMWindow.cpp:287 src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "&Quellen anzeigen\tCtrl-S\tQuellen-Browser anzeigen " #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Vollbild\tF12\tVollbildmodus umschalten" #: src/GMWindow.cpp:296 #, fuzzy msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Fernbedienung anzeigen\tF11\tZeige ein kleines Wiedergabefenster an." #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "&Sortierung" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "Zum aktuellen Titel &springen\tCtrl-J\tZeige den aktuellen Titel an." #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Steuerung" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Play\tCtrl-P\tStarte die Wiedergabe." #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Stopp\tCtrl-\\\tDie Wiedergabe anhalten." #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Vorherigen Titel\tCtrl-[\tGib den vorherigen Titel wieder." #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Nächsten Titel\tCtrl-]\tGib den nächsten Titel wieder." #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Wiederholung aus\tCtrl-,\tWiederhole den aktuellen Titel." #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Wiederholung\tCtrl-.\tWiederhole den aktuellen Titel." #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Wiederhole alle Titel\tCtrl-/\tWiederhole alle Titel." #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "" "Wiederholung A-B\tCtrl-T\tWiederhole die Titel, die sich zwischen zwei " "ausgewählten Titeln befinden" #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "" "Zufällige Wiedergabe\tAlt-R\tGib die Titel in eine zufälligen Reihenfolge " "wieder" #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Equalizer\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Zeitschaltuhr\t\tDie Zeitschaltuhr einstellen." #: src/GMWindow.cpp:323 msgid "&Help" msgstr "&Hilfe" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "&Homepage" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "Einen Fehle&r melden…" #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "Bei last.fm &anmelden…" #: src/GMWindow.cpp:328 msgid "" "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "" "GMM auf last.fm b&eitreten…\t\tTreten Sie der Goggles Music Manager-Gruppe " "auf last.fm bei…" #: src/GMWindow.cpp:330 msgid "&About…" msgstr "Ü&ber" #: src/GMWindow.cpp:842 src/GMWindow.cpp:940 msgid "Pause" msgstr "Pause" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Vorheriges" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Nächstes" #: src/GMWindow.cpp:920 src/GMWindow.cpp:949 src/GMWindow.cpp:955 msgid "Start playback." msgstr "Starte die Wiedergabe." #: src/GMWindow.cpp:926 src/GMWindow.cpp:927 #, fuzzy msgid "Start playback" msgstr "Starte die Wiedergabe." #: src/GMWindow.cpp:934 src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Die Wiedergabe pausieren." #: src/GMWindow.cpp:935 #, fuzzy msgid "Pause playback" msgstr "Die Wiedergabe pausieren." #: src/GMWindow.cpp:1052 src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Wiederhole A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Wiederhole A" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "" #: src/GMWindow.cpp:1202 #, fuzzy msgid "Please specify a file or url to play:" msgstr "Bitte eine Adresse zum Abspielen eingeben" #: src/GMWindow.cpp:1206 #, fuzzy msgid "…" msgstr "Bearbeiten…" #: src/GMWindow.cpp:1212 #, fuzzy msgid "Select File" msgstr "Alles Auswählen" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Zeitschaltuhr" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Einstellung der Zeitschaltuhr" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Die Wiedergabe nach einen bestimmten Zeit anhalten" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "Die Uhr &starten" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Stoppe in" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "Stunden und" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "Minuten." #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Musikbibliothek" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Internet-Radio" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "B&eenden" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "Über&springen" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "&Alle Überspringen" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "&Nicht Speichern" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tFarbe wählen" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tFarbton, Sättigung, Wert" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tRot, Grün, Blau" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "&Rot:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Grün:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "&Blau:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alpha:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Farbton:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Sättigung:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Wert:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alpha:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tZyan, Magenta, Gelb" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Zyan:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Magenta:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Gelb:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tNach Name" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Neues Verzeichnis anlegen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Existiert bereits" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Kann nicht erstellt werden" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Kopiere Datei" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Fehler während des Kopierens" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Verschiebe Datei" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Fehler während des Verschiebens" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Verknüpfung erstellen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Fehler während der Erstellung der Verknüpfung" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "Datei löschen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Fehler während dem Löschen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Eine Ebene nach oben" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Heimverzeichnis" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Arbeitsverzeichnis" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Sortierung" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Groß-/Kleinschreibung ignorieren" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Versteckte Dateien" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Lesezeichen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Lesezeichen erstellen" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Lesezeichen leeren" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Neues Verzeichnis..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Kopieren..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Verschieben..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Verknüpfung erstellen..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Löschen..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Änderungsdatum" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Benutzer" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Gruppe" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Attribute" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Verknüpfung" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Erstelle neues Verzeichnis mit dem Namen: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "Datei oder Verzeichnis %s existiert bereits.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Das Verzeichnis %s kann nicht erstellt werden.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Kopiere Datei von:\n" "\n" "%s\n" "\n" "nach: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Konnte die Datei nicht von:\n" "\n" "%s nach: %s kopieren.\n" "\n" "Trotzdem fortfahren?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Verschiebe Datei von:\n" "\n" "%s\n" "\n" "nach: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Konnte die Datei nicht von:\n" "\n" "%s nach: %s verschieben.\n" "\n" "Trotzdem fortfahren?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Erstelle Verknüpfung\n" "\n" "%s\n" "\n" "mit: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Konnte keine Verknüpfung\n" "\n" "%s mit: %s erstellen.\n" "\n" "Trotzdem fortfahren?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "Dateien werden gelöscht" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Sind Sie sicher, dass Sie die folgende Datei löschen wollen:\n" "\n" "%s" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "Die Datei:\n" "\n" "%s konnte nicht gelöscht werden.\n" "\n" "Trotzdem fortfahren?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Alles Auswählen" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Sortieren nach" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Ansicht" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Kleine Symbole" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Große Symbole" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Details" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Zeilen" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Spalten" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Vorschaubild" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Normalgroße Bilder" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Mittelgroße Bilder" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Große Bilder" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "E&rsetzen" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Alle Erset&zen" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "Such&en nach:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Ersetzen &mit:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "Extr&ahieren" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "Groß-/Kleinschreibung ignorieren" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "Ausdrücke" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Rückwärts" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "&Suchen" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Bereit." #~ msgid "Old Name" #~ msgstr "Alter Name" #~ msgid "New Name" #~ msgstr "Neuer Name" #~ msgid "Pitch:" #~ msgstr "Abstand:" #~ msgid "Any" #~ msgstr "Beliebig" #~ msgid "Fixed" #~ msgstr "Fest" #~ msgid "Variable" #~ msgstr "Variabel" #, fuzzy #~ msgid " Type:" #~ msgstr "Typ" #, fuzzy #~ msgid "Scalable" #~ msgstr "Skalierbar:" #, fuzzy #~ msgid "Size:" #~ msgstr "Größe" #, fuzzy #~ msgid "Family:" #~ msgstr "&Familie:" #~ msgid "Always Show Remote" #~ msgstr "Die Fernbedienung immer anzeigen" #~ msgid "Source\tActive Source Color" #~ msgstr "Quelle\tFarbe der aktiven Quelle" #~ msgid "About" #~ msgstr "Über" #~ msgid "" #~ "An incompatible version of SQLite (%s) is being used.\n" #~ "Goggles Music Manager requires at least SQLite 3.3.8.\n" #~ "Please upgrade your SQLite installation." #~ msgstr "" #~ "Eine inkompatible SQLite-Version (%s) wird benutzt.\n" #~ "Goggles Music Manager benötigt mindestens Version 3.3.8.\n" #~ "Bitte aktualisieren Sie ihre Version von SQLite." #~ msgid "" #~ "This version of SQLite (%s) is broken.\n" #~ "Please upgrade your SQLite installation to at least 3.6.3." #~ msgstr "" #~ "Diese SQLite-Version (%s) ist defekt.\n" #~ "Bitte aktualisieren Sie SQLite auf mindestens Version 3.6.3." #~ msgid "" #~ "&Join GMM on last.fm…\tJoin the Goggles Music Manager group on last.fm…" #~ "\tJoin the Goggles Music Manager group on last.fm…" #~ msgstr "" #~ "GMM auf last.fm &beitreten…\tTreten Sie der Goggles Music Manager-Gruppe " #~ "auf last.fm bei…\tTreten Sie der Goggles Music Manager-Gruppe auf last.fm " #~ "bei…" #~ msgid "Font" #~ msgstr "Schrift" #~ msgid "Theme Directory:" #~ msgstr "Themenverzeichnis:" #~ msgid "Select Theme Directory" #~ msgstr "Themenverzeichnis wählen" #~ msgid "thin" #~ msgstr "dünn" #~ msgid "normal" #~ msgstr "normal" #~ msgid "bold" #~ msgstr "fett" #~ msgid "regular" #~ msgstr "regulär" #~ msgid "&Weight:" #~ msgstr "&Breite:" #~ msgid "&Style:" #~ msgstr "&Stil" #~ msgid "Si&ze:" #~ msgstr "&Größe" #~ msgid "Character Set:" #~ msgstr "Zeichensatz:" #~ msgid "West European" #~ msgstr "West-Europäisch" #~ msgid "East European" #~ msgstr "Ost-Europäisch" #~ msgid "South European" #~ msgstr "Süd-Europäisch" #~ msgid "North European" #~ msgstr "Nord-Europäisch" #~ msgid "Cyrillic" #~ msgstr "Kyrillisch" #~ msgid "Arabic" #~ msgstr "Arabisch" #~ msgid "Greek" #~ msgstr "Griechisch" #~ msgid "Hebrew" #~ msgstr "Hebräisch" #~ msgid "Turkish" #~ msgstr "Türkisch" #~ msgid "Thai" #~ msgstr "Thai" #~ msgid "Baltic" #~ msgstr "Baltisch" #~ msgid "Russian" #~ msgstr "Russisch" #~ msgid "Central European (cp1250)" #~ msgstr "Zentral-Europäisch (cp1250)" #~ msgid "Russian (cp1251)" #~ msgstr "Russisch (cp1251)" #~ msgid "Latin1 (cp1252)" #~ msgstr "Latin1 (cp1252)" #~ msgid "Greek (cp1253)" #~ msgstr "Griechisch (cp1253)" #~ msgid "Turkish (cp1254)" #~ msgstr "Türkisch (cp1254)" #~ msgid "Hebrew (cp1255)" #~ msgstr "Hebräisch (cp1255)" #~ msgid "Arabic (cp1256)" #~ msgstr "Arabisch (cp1256)" #~ msgid "Baltic (cp1257)" #~ msgstr "Baltisch (cp1257)" #~ msgid "Vietnam (cp1258)" #~ msgstr "Vietnamesisch (cp1258)" #~ msgid "Thai (cp874)" #~ msgstr "Thai (cp874)" #~ msgid "UNICODE" #~ msgstr "UNICODE" #~ msgid "Set Width:" #~ msgstr "Wähle Breite:" #~ msgid "All Fonts:" #~ msgstr "Alle Schriftarten:" #~ msgid "Preview:" #~ msgstr "Vorschau:" #, fuzzy #~ msgid "Import Playlist…\t\tImport a existing playlist" #~ msgstr "Neue &Wiedergabeliste…\t\tErstelle eine neue Wiedergabeliste" #~ msgid "Import Files?" #~ msgstr "Dateien importieren?" #~ msgid "" #~ "Would you like import the pasted files and/or directories into the Music " #~ "Library?" #~ msgstr "" #~ "Möchten Sie die eingefügten Dateien und/oder Verzeichnisse in die " #~ "Musikbibliothek importieren?" #~ msgid "" #~ "%s\n" #~ "by: %s\n" #~ "from: %s" #~ msgstr "" #~ "%s\n" #~ "von: %s\n" #~ "aus: %s" #~ msgid "Now Playing" #~ msgstr "Aktueller Titel" #~ msgid "Open URL…\t\tOpen Stream or File" #~ msgstr "URL ö&ffnen…\t\tInternetstream oder Datei öffnen" #~ msgid "Open MRL" #~ msgstr "MRL öffnen" #~ msgid "P&ause" #~ msgstr "P&ause" #~ msgid "\tPause\tPause Playback" #~ msgstr "\tPause\tWiedergabe pausieren" #~ msgid "A capella" #~ msgstr "A capella" #~ msgid "Acid" #~ msgstr "Acid" #~ msgid "Acid Jazz" #~ msgstr "Acid Jazz" #~ msgid "Acid Punk" #~ msgstr "Acid Punk" #~ msgid "Acoustic" #~ msgstr "Akustisch" #~ msgid "Alternative" #~ msgstr "Alternative" #~ msgid "Avantgarde" #~ msgstr "Avantgarde" #~ msgid "Ballad" #~ msgstr "Ballade" #~ msgid "Bass" #~ msgstr "Bass" #~ msgid "Bebob" #~ msgstr "Bebob" #~ msgid "Big Band" #~ msgstr "Big Band" #~ msgid "Blues" #~ msgstr "Blues" #~ msgid "Bluegrass" #~ msgstr "Bluegrass" #~ msgid "Booty Bass" #~ msgstr "Booty Bass" #~ msgid "Cabaret" #~ msgstr "Kabarett" #~ msgid "Chamber Music" #~ msgstr "Kammermusik" #~ msgid "Chanson" #~ msgstr "Chanson" #~ msgid "Chorus" #~ msgstr "Chor" #~ msgid "Classical" #~ msgstr "Klassik" #~ msgid "Classic Rock" #~ msgstr "Classic Rock" #~ msgid "Club" #~ msgstr "Club" #~ msgid "Comedy" #~ msgstr "Comedy" #~ msgid "Country" #~ msgstr "Country" #~ msgid "Dance" #~ msgstr "Dance" #~ msgid "Dance Hall" #~ msgstr "Dance Hall" #~ msgid "Darkwave" #~ msgstr "Darkwave" #~ msgid "Death Metal" #~ msgstr "Death Metal" #~ msgid "Disco" #~ msgstr "Disco" #~ msgid "Drum Solo" #~ msgstr "Schlagzeugsolo" #~ msgid "Duet" #~ msgstr "Duet" #~ msgid "Easy Listening" #~ msgstr "Easy Listening" #~ msgid "Electronic" #~ msgstr "Elektronische Musik" #~ msgid "Folk" #~ msgstr "Folk" #~ msgid "Folk-Rock" #~ msgstr "Folk-Rock" #~ msgid "Folklore" #~ msgstr "Folklore" #~ msgid "Funk" #~ msgstr "Funk" #~ msgid "Gospel" #~ msgstr "Gospel" #~ msgid "Gothic" #~ msgstr "Gothic" #~ msgid "Gothic Rock" #~ msgstr "Gothic Rock" #~ msgid "Grunge" #~ msgstr "Grunge" #~ msgid "Hard Rock" #~ msgstr "Hard Rock" #~ msgid "Hip-Hop" #~ msgstr "Hip-Hop" #~ msgid "House" #~ msgstr "House" #~ msgid "Industrial" #~ msgstr "Industrial" #~ msgid "Instrumental" #~ msgstr "Instrumental" #~ msgid "Jazz" #~ msgstr "Jazz" #~ msgid "Jazz+Funk" #~ msgstr "Jazz+Funk" #~ msgid "Meditative" #~ msgstr "Meditativ" #~ msgid "Metal" #~ msgstr "Metal" #~ msgid "Musical" #~ msgstr "Musical" #~ msgid "New Age" #~ msgstr "New Age" #~ msgid "New Wave" #~ msgstr "New Wave" #~ msgid "Noise" #~ msgstr "Noise" #~ msgid "Oldies" #~ msgstr "Oldies" #~ msgid "Opera" #~ msgstr "Oper" #~ msgid "Other" #~ msgstr "Andere" #~ msgid "Polka" #~ msgstr "Polka" #~ msgid "Pop" #~ msgstr "Pop" #~ msgid "Pop-Folk" #~ msgstr "Pop-Folk" #~ msgid "Pop/Funk" #~ msgstr "Pop/Funk" #~ msgid "Progressive Rock" #~ msgstr "Progressive Rock" #~ msgid "Psychadelic" #~ msgstr "Psychadelic" #~ msgid "Psychedelic Rock" #~ msgstr "Psychedelic Rock" #~ msgid "Punk" #~ msgstr "Punk" #~ msgid "Punk Rock" #~ msgstr "Punk Rock" #~ msgid "R&B" #~ msgstr "R&B" #~ msgid "Rap" #~ msgstr "Rap" #~ msgid "Rave" #~ msgstr "Rave" #~ msgid "Reggae" #~ msgstr "Reggae" #~ msgid "Retro" #~ msgstr "Retro" #~ msgid "Revival" #~ msgstr "Revival" #~ msgid "Rock" #~ msgstr "Rock" #~ msgid "Rock & Roll" #~ msgstr "Rock & Roll" #~ msgid "Samba" #~ msgstr "Samba" #~ msgid "Satire" #~ msgstr "Satire" #~ msgid "Ska" #~ msgstr "Ska" #~ msgid "Sonata" #~ msgstr "Sonate" #~ msgid "Soul" #~ msgstr "Soul" #~ msgid "Soundtrack" #~ msgstr "Soundtrack" #~ msgid "Speech" #~ msgstr "Sprache" #~ msgid "Swing" #~ msgstr "Swing" #~ msgid "Symphony" #~ msgstr "Symphonie" #~ msgid "Tango" #~ msgstr "Tango" #~ msgid "Techno" #~ msgstr "Techno" #~ msgid "Top 40" #~ msgstr "Top 40" #~ msgid "Trailer" #~ msgstr "Trailer" #~ msgid "Trance" #~ msgstr "Trance" #~ msgid "Tribal" #~ msgstr "Tribal" #~ msgid "Trip-Hop" #~ msgstr "Trip-Hop" #~ msgid "Vocal" #~ msgstr "Gesang" #~ msgid "Start Up:" #~ msgstr "Einschalten:" #~ msgid "Show Main Window" #~ msgstr "Zeige Hauptfenster" #~ msgid "Show Mini Remote" #~ msgstr "Zeige Fernbedienung" #~ msgid "Previous View" #~ msgstr "Vorherige Ansicht" #~ msgid "Configure Columns…" #~ msgstr "Spalten &konfigurieren…" #~ msgid "Yes" #~ msgstr "Ja" #~ msgid "Edit…\tF2\tEdit Genre." #~ msgstr "Bearbeiten…\tF2\tGenre bearbeiten." #~ msgid "Edit…\tF2\tEdit Artist." #~ msgstr "Bearbeiten…\tF2\tKünstlername bearbeiten." #~ msgid "Edit…\tF2\tEdit Album." #~ msgstr "Bearbeiten…\tF2\tAlbumname bearbeiten." gogglesmm-0.12.7/po/es.mo0000644000175000001440000011530112063217121013663 0ustar sxjusersL))()* *+;*g*-~*0*1*5+E+ ]+!i+)+++++++1+50,-f,.,,,,z- I.7T. .... ..3.."./!$/F/\/!e/// / / /// ////0 0 0#0K+09w00000'000"01#1 +171?1H1Y1_1*g11 1111 11 1112 22W2Fq2 22 2 2B2'3/3 H3V3 e3 s3~333*4-4-4$5C+5o5 x55 5555 555 6 66#6*61676 ?6M6j6 66<666677 7*7J7\74p7'7 7+78 8 8 08Q8Y8`8f81u8 888 8 8 88 9 99 '929;9"@9 c9o9 999 9"9 99 9 : :::0:D:W:"i::C::: :: ;;'; 8;2F;3y;';2; < < <))< S< _<4m<<%<<<<%<="&=I=R=W>h> n>{>b?h? n?{???? ??=? @@,%@8R@@ @"@@@@ @ AA A+A1A 6A+@AlAtA }A AAAAA AA AOA ?B IBSB+[BB BBBBB)B C&%C+LCxC CCC%C C&C DWDfDjDqD DDD+DDDD EE E 1E;EAE\EkE{EE"EE+EEFF'FCF%]F#FF FF9F GGG(G11GcG&rGGG G G GGG G5G!H0HFH ZH.hH!HHH)HI"I+BI&nI(I'I)IJ (J.IJ&xJ(J(J4J+&K-RKKKK K*K+K'L)?LiLxLL L*LLL L M M!M*M ;MGM ZMeMMJMDM N(N%?NeNwN'N)N N,NO 3O?OLOO1OCOEPXP/gPP P PPP P PPPQCQ ZQ*{QQQQQQ Q#R2R89RrRR RRR S1S1SStTlyTTT TTU U%U+U3U!NUpUi%z%ƈ)߈ " 3@I\p( ĉdΉ]3$?Ŋ776oB($6aN@]iO:ʍ &( OYj A53+_u !-)Hg~  27*ʒoҒ BLTh ")ȓ/"D'#l>.ϕ0#/ESC!ݖ+,+,X1-)K/{ ט "7O0męיޙ  ' ,'6!^J"ge?zv;e+FU3]/ 5:5FWwpHSpBx^+t>i=d|}CTK`I)O@ :X(kaQ'8mz>c(Ah4fV!\69ZlukX]-G%_q g& fl&?M7 o<[$YYB J3{AVn8hLNq1oKPuC[)DE*@4Q',j=r7} Mwj"x{n<_6d%* /Um-\2EN~Osvs9,# #PRtbZyTa~..iW!D$G;cbLI1rR`y|20 ^0 S H Adjust Volume Adjust Volume Bookmarks Visit bookmarked directories. By Name Close Filter Close Filter Create new directory Create new directory. Cyan, Magenta, Yellow Go to home directory Back to home directory. Go to work directory Back to working directory. Go up one directory Move up to higher directory. Hide Hidden Files Hide hidden files and directories. Hue, Saturation, Value Pick color Play Next Track Play next track. Play Previous Track Play previous track. Red, Green, Blue Remove Reset Save Separate Artists Shared Artists Show details Display detailed directory listing. Show hidden files Show hidden files and directories. Show icons Display directory with big icons. Show list Display directory with small icons. Start Playback Start Playback Stop Playback Stop Playback%T - title %A - album name %P - album artist name %p - track artist name %y - year %d - disc number %N - track number (2 digits) %n - track number %G - genre%T - title %A - album name %P - album artist name %p - track artist name %N - track number %G - genre%s %s (%d)%s Please contact support if this error keeps occuring.&About…&Accept&Alpha:&Audio&Backward&Blue:&Browse Ctrl-B Show genre artist and album browser.&Cancel&Clear bookmarks Clear bookmarks.&Close&Columns Change Visible Columns.&Configure Columns…&Control&Copy Ctrl-C Copy Selected Tracks&Create&Cut Ctrl-X Cut Selected Tracks&Directory&Directory:&Don't Save&Edit&Export&File Name:&File(s)&General&Green:&Help&Homepage&Ignore Case&Import&Join GMM on last.fm… Join the Goggles Music Manager group on last.fm…&Jump to Current Track Ctrl-J Show current playing track.&Music&Next&No&OK&Paste Ctrl-V Paste Clipboard Selection&Play&Quit&Quit Ctrl-Q Quit the application.&Red:&Remove&Remove All&Rename&Replace&Report Issue…&Save&Search&Set bookmark Bookmark current directory.&Sign up for last.fm…&Sign up…&Skip&Sort&Sort Change Sorting.&Start Timer&Stop&Stop Import&Sync&Track&View&Window&Yes?c - display a if c is not empty else display b. ?c - display c if not empty A DBus error occurred. All features requiring sessionbus are disabled.A&ppearanceAlbumAlbum ArtistAlbum CoversAlbums Press to change sorting order Press to change sorting orderAlbums:All Always read the tagsAll %d AlbumsAll %d ArtistsAll %d GenresAll GenresAlpha:Already ExistsAn incompatible (future) version of the database was found. This usually happens when you try to downgrade to a older version of GMM Press OK to continue and reset the database (all information will be lost!). Press Cancel to quit now and leave the database as is.Are you sure you want to delete %s preset?Are you sure you want to delete the file: %sAre you sure you want to delete the playlist?ArtistArtists Press to change sorting order Press to change sorting orderArtists:AttributesAudio Device ErrorAudio Driver:Audio output unavailable.Auto track number. Offset:Base Base ColorBig iconsBitrateBoldBookmarksBorder Border ColorBothBottomBrowseBy %sC&reateCannot CreateCannot create directory %s. Change playlist nameChange…ChannelsChoose the order of information to appear in the track list.Clear Music Library?Clear bookmarksClose audio device on pause.ColorsColumnsCondensedConditions may be used as well:Configure ColumnsConnection Refused.Copy Ctrl-C Copy associated tracks to the clipboard.Copy Ctrl-C Copy track(s) to clipboard.Copy FileCopy file from location: %s to location: Copy...Create New DirectoryCreate PlaylistCreate new directory with name: CurrentCustomCyan:Database ErrorDatabase Error: Unable to retrieve all filenames.Default FontDefault value:Delete Play List?Delete PresetDelete...Deleting fileDeleting filesDemiboldDescriptionDetailsDirectory:DisabledDiscDisplay playing track in title barE&xpressionEdit Internet Radio StationEdit PlaylistEdit Track InformationEdit…Edit… Edit… F2 Edit Track Information.Encoding:EngineEqualizerEqualizer Equalizer:ErrorError Copying FileError Deleting FileError Linking FileError Moving FileError while loading library/pluginEx&actExclude Filter Filter out directories and/or files based on patternExclude:ExpandedExport AlbumsExport ArtistsExport GenreExport Main LibraryExport Play ListExport TracksExport tracks from album to destination directory.Export tracks from artist to destination directory.Export tracks to destination directory.Export tracks with genre to destination directory.Export…Extra BoldExtra LightFailed to open requested audio driver: %sFatal ErrorFile F&ilter:File already exists. Would you like to overwrite it?File not found.File or directory %s already exists. File:FilenameFilename TemplateFilenames did not require any changesFiles:Find… Ctrl-F Show search filter.Folders:For some reason the FOX library was compiled without PNG support. In order to show all icons, Goggles Music Manager requires PNG support in the FOX library. If you've compiled FOX yourself, most likely the libpng header files were not installed on your system.Gapless playbackGenreGiant imagesGoggles Music Manager was unable to open the database. The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again. if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmmGroupHeavyHidden filesHilite Hilite ColorHome directoryHue:IconsIgnore caseIgnore leading wordsImport Folder… Ctrl-O Import Music from folder into LibraryImport MusicImport PlaylistImport Playlist… Import existing playlistImport new tracks Imports files not yet in the database.Importing Files...Import…Information… Library StatisticsInternet RadioInvalid TemplateKeep play listsLarge IconsLast.FM ErrorLast.fmLibrary ErrorLightLinkLink FileLink file from location: %s to location: Link...LocationLocation:Lower caseLower case extensionMagenta:ManualMediumMedium imagesMenu Menu Text ColorModified DateModified since last import Only reread the tag when the file has been modified.Move DownMove FileMove UpMove file from location: %s to location: Move...Music LibraryMusic Library InformationNameNetwork not reachable.New Internet Radio StationNew Play List… Create a new play list.New PlaylistNew Playlist… Create a new playlistNew Radio Station… Create a new playlistNew Station… New Tracks:New directory...NextNext Play Next Track Play next track.Next TrackNext Track Ctrl-] Play previous track.No changesNo tracks were updated. Would you still like to write the tags for the selected tracks?No.NormalNormal Normal Text ColorNormal imagesOffOops. Database ErrorOpen Folder Location Open Folder Location.Options:Overwrite File?Overwrite PresetP&reviousParse SettingsParse info from:Password:PausePause Pause Pause PlaybackPause playbackPause playback.PlayPlay Ctrl-P Start playback.Play Start Playback Start PlaybackPlay File or StreamPlay File or Stream… Play File or StreamPlaybackPlayback ErrorPlayer ControlsPlaying Playing Track ColorPlease enter preset name:Please specify a file or url to play:Please wait. This may take a while.Pre-ampPreferencesPreferences…Preset %s already exists. Would you like to overwrite it?Preset NamePresets:Preview imagesPreviousPrevious Play Previous Track Play previous track.Previous TrackPrevious Track Ctrl-[ Play next track.QueueQuitRe&place AllRead ErrorRead OnlyReady.Remove Remove.Remove Album?Remove All Tracks Remove all tracks from the libraryRemove Artist?Remove Audio Files...Remove Audio Files?Remove Genre?Remove Internet Radio Station(s) from library?Remove Internet Radio Station(s)?Remove PlaylistRemove Track(s)?Remove all tracks from the music library?Remove track(s) from library?Remove track(s) from play list?Remove tracks found in folder from databaseRemove tracks from album from library?Remove tracks from album from play list?Remove tracks from artist from library?Remove tracks from artist from play list?Remove tracks from diskRemove tracks from music libraryRemove tracks that have been deleted from diskRemove tracks with genre from library?Remove tracks with genre from play list?Remove… Del Remove Genre from Library.Remove… Del Remove associated tracks from library.Remove… Del Remove track(s) from library.Remove… Del Remove track(s) from play list.Rename Audio Files?Renaming Audio Files…Repeat ARepeat A-BRepeat A-B Ctrl-T Repeat section of track.Repeat All Tracks Ctrl-/ Repeat all tracks.Repeat Off Ctrl-, Repeat current track.Repeat Track Ctrl-. Repeat current track.Replace &with:Replace spaces with underscoresReplace underscores with spacesReplay Gain:Resource not accessible. Check permissionsReverseRowsS&earch for:SamplerateSaturation:ScrobbleSecurity WarningSelect FileSelect Normal FontSelect allSelected Selected Text ColorService:Session Bus not available. All features requiring sessionbus are disabled.Session bus not available. All features requiring dbus are disabled.Set bookmarkSet export template…Set track number based on scan order.Setup sleep timerShadow Shadow ColorShow &Genres Ctrl-G Show genre browser.Show &Sources Ctrl-S Show source browser Show BrowserShow Full Screen F12 Toggle fullscreen mode.Show Icons in Track BrowserShow LabelsShow Status BarShow Track Change Notifications Inform notification daemon of track changes.Show Tray Icon Show tray icon in the system tray.Show album cover of playing track Show album cover of playing trackShow album covers in album browser Show album covers in album browserShuffle Ctrl-RShuffle Mode Alt-R Play tracks in random order.SizeSkip &AllSleep TimerSleep Timer Setup sleeptimer.Sleep inSmall iconsSort OptionsSort bySort by Album YearSortingSources Press to change sorting order Press to change sorting orderSpecify name of the new playlistSpecify url and description of new stationStart playbackStart playback.StationStopStop Ctrl-\ Stop playback.Stop Stop Playback Stop PlaybackStop playback within a certain timeStyle:Sync Folder… Synchronize Folder with Music in LibrarySync OperationSynchronize FolderSystem TrayTagTemplate may contain absolute or relative path, environment variables and ~. Relative paths are based on the location of the original file. The file extension gets automatically added. The following macros may be used:Template:The following audio files are going to be removedThe following audio files are going to be renamedThe provided template is invalid. The track title %%T needs to be specified. Please fix the filename template in the preference panel.ThinThis version of Goggles Music Manager is not supported by Last-FM. Please upgrade to a newer version of GMM.TimeTitleTitle Format:Tooltip Tooltip ColorTopTotal Time:TrackTracks:Tray Tray Background ColorTurn off playback engine on stop.Turn on playback engine on startup. For faster startup, playback engine is normally started when first track is played. For faster startup, playback engine is normally started when first track is played.TypeUnable to copy file: %s to: %s Continue with operation?Unable to create directory %s Unable to delete file: %s Continue with operation?Unable to initialize audio driver.Unable to insert track into the databaseUnable to launch webbrowserUnable to link file: %s to: %s Continue with operation?Unable to move file: %s to: %s Continue with operation?Unable to open the databaseUnable to remove album from the libraryUnable to remove artist from the libraryUnable to remove genre from the libraryUnable to remove station from the library.Unable to remove track from the library.Unable to rename fileUnable to rename: %s to:%sUnable to rename: %s to:%s Continue renaming files?Unable to update trackUnknown ErrorUnknown deviceUnknown host.UntitledUp one levelUpdate FilenameUpdate Tag in FileUpdate Tags?Update existing tracks:Update url and description of stationUpdating Database...UserUsername:Value:ViewVolume NormalizationWarningWindowWork directoryYearYellow:You music collection consists of…alt bg Alternative Background Colorbg Background Colorfg Foreground Colorhours andminutes.…Project-Id-Version: gogglesmm 0.10.x Report-Msgid-Bugs-To: s.jansen@gmail.com POT-Creation-Date: 2011-02-09 23:26-0600 PO-Revision-Date: 2011-01-23 13:33+0100 Last-Translator: Víctor Pérez Masegosa Language-Team: Spanish Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Lokalize 1.1 Ajustar volumen Ajustar volumen Marcadores Visitar directorios con marcadores. Por Nombre Cerrar Filtro Cerrar Filtro Crear nuevo directorio Crear nuevo directorio. Cian, Magenta, Amarillo Ir al directorio de usuario Volver al directorio de usuario. Ir al directorio de trabajo Volver al directorio de trabajo. Subir un directorio Subir al directorio superior. Ocultar Archivos Ocultos Ocultar archivos y directorios ocultos. Tono, saturación, valor Elige color Reproducir pista siguiente Reproducir pista siguiente. Reproducir pista anterior Reproducir pista anterior. Rojo, Verde, Azul Eliminar Reiniciar Guardar Separar artistas Artistas compartidos Mostrar detalles Mostrar listado de directorio detallado. Mostrar archivos ocultos Mostrar archivos y directorios ocultos. Mostrar iconos Mostrar directorio con iconos grandes. Mostrar lista Mostrar directorio con iconos pequeños. Empezar reproducción Empezar reproducción Parar reproducción Parar reproducción%T - título %A - nombre del album %P - nombre del artista del album %p - nombre del artista de la pista %y - año %d - número del disco %N - número de pista (2 dígitos) %n - número de pista %G - género%T - título %A - nombre del album %P - nombre del artista del album %p - nombre del artista de la pista %N - nombre de la pista %G - género%s %s (%d)%s Por favor, contacta con soporte si este error continúa ocurriendo.&Acerca de...&Aceptar&Alfa:&Audio&Hacia Atrás&Azul:&Navegar Ctrl-B Mostrar navegador de género, artista y álbum.&Cancelar&Limpiar marcadores Limpiar Marcadores.&Cerrar&Columnas Cambiar columnas visibles.&Configurar Columnas...&Control&Copiar Ctrl-C Copiar las Pistas Seleccionadas&Crear&Cortar Ctrl-X Cortar las Pistas Seleccionadas&Directorio&Directorio:&No Guardar&Editar&Exportar&Nombre de Archivo:&Archivo(s)&General&Verde:&Ayuda&Página principal&Ignorar mayúsculas y minúsculas&Importar&Únete a GMM en last.fm... Únete al grupo de Goggles Music Manager en last.fm...&Saltar a la Pista Actual Ctrl-J Mostrar la pista que se está reproduciendo.&Música&Siguiente&No&OK&Pegar Ctrl-V Pegar la selección del Portapapeles&Reproducir&Salir&Salir Ctrl-Q Salir de la aplicación.&Rojo:&Eliminar&Eliminar todo&Renombrar&Reemplazar&Reportar Problema...&Guardar&Búsqueda&Crear marcador Añadir el directorio actual a marcadores.&Regístrate en Last.fm...&Regístrate...&Saltar&Ordenar&Orden Cambiar orden.&Iniciar Temporizador&Parar&Parar importación&Sincronizar&Pista&Ver&Ventana&Sí?c - mostrar a si c no está vacío. Si no, mostrar b. ?c - mostrar c si no está vacío Ha ocurrido un error en DBus. Todas las características que requieren dbus están desactivadas.A&parienciaÁlbumArtista del álbumCarátulasÁlbumes Pulsar para cambiar el orden Pulsar para cambiar el ordenÁlbumes:Todas Siempre leer las etiquetasTodos %d los álbumesTodos %d los artistasTodos %d los génerosTodos los génerosAlfa:Ya ExisteUna incompatible (futura) versión de la base de datos ha sido encontrada. Suele pasar cuando intentas hacer un downgrade a una versión más antigua de GMM Presiona OK para continuar y resetear la base de datos (¡Se perderá toda la información!). Presiona Cancelar para salir ahora mismo y dejar la base de datos como está.¿Estás seguro de que quieres eliminar la predefinición %s?Estás seguro de que quieres borrar el archivo: %s¿Estás seguro de que quieres eliminar la lista de reproducción?ArtistaArtistas Pulsar para cambiar el orden Pulsar para cambiar el ordenArtistas:AtributosError del dispositivo de audioControlador de audio:Salida de audio no disponible.Número de pista automático. Compensación:Base Color baseIconos grandesTasa de bitsNegritaMarcadoresBorde Color de bordeAmbos:AbajoNavegarPor %sC&rearNo se pudo crearNo se puede crear el directorio %s. Cambiar el nombre de la lista de reproducciónCambiar...CanalesElije en qué orden aparecerá la información en la lista de reproducción.¿Limpiar biblioteca de música?Limpiar marcadoresCerrar el dispositivo de audio en pausa.ColoresColumnasColapsadoTambién pueden ser usadas condiciones:Configurar columnasConexión rechazada.Copiar Ctrl-C Copiar pistas asociadas al portapapeles.Copiar Ctrl-C Copiar pista(s) al portapapeles.Copiar ArchivoCopiar archivo de: %s a:Copiar...Crear Nuevo DirectorioCrear lista de reproducciónCrear nuevo directorio con nombre:ActualPersonalizadoCian:Error de base de datosError de base de datos: No se pudieron recuperar todos los nombres de archivos.Fuente por defecto:Valor por defecto:¿Eliminar lista de reproducción?Eliminar predefiniciónEliminar...Borrando archivoBorrando archivosCuasi negritaDescripciónDetallesDirectorio:DesactivadoDiscoMostrar la pista en reproducción en la barra de títuloE&xpresiónEditar estación de radio de InternetEditar lista de reproduciónEditar la información de la pistaEditar...Editar... Editar... F2 Editar información de la pista.Encodificado:MotorEcualizadorEcualizador Ecualizador:ErrorError Copiando ArchivoError Borrando ArchivoError Enlazando ArchivoError Moviendo ArchivoError al cargar la librería/complementoEx&actoExcluir filtro Filtrar directorios y/o archivos basados en el patrónExcluir:ExpandidoExportar álbumesExportar artistasExportar géneroExportar biblioteca principalExportar lista de reproducciónExportar pistasExportar pistas del álbum al directorio de destino.Exportar pistas del artista al directorio de destino.Exportar pistas al directorio de destino.Exportar pistas con género al directorio de destino.Exportar...Extra negritaExtra ligeraNo se pudo inicializar el controlador de audio: %sError FatalF&iltro de Archivos:El archivo ya existe. ¿Quieres sobrescribirlo?Archivo no encontrado.El archivo o directorio %s ya existe. Archivo:Nombre de archivoPlantilla de nombres de archivoLos nombres de los archivos no requirieron cambiosArchivos:Buscar... Ctrl-F Mostrar filtro de búsqueda.Carpetas:Por alguna razón, la librería FOX fue compilada sin soporte para PNG. Para poder ver todos los iconos, Goggles Music Manager necesita soporte para PNG en la librería FOX. Si has compilado FOX por ti mismo, lo más probable es que encabezados de libpng no fueran instalados en tu sistema.Reproducción sin espaciosGéneroImágenes gigantesGoggles Music Manager no pudo abrir la base de datos. La base de datos puede haberse corrompido. Por favor, elimina ~/.goggles/goggles.db y prueba de nuevo. Si el error sigue ocurriendo, por favor, avísanos del problema en http://code.google.com/p/gogglesmmGrupoPesadaArchivos ocultosDestacado Color del destacadoDirectorio personalTono:IconosIgnorar mayúsculas o minúsculasIgnorar las primeras palabrasImportar carpeta... Ctrl-O Importar música de una carpeta a la bibliotecaImportar músicaImportar lista de reproducciónImportar lista de reproducción... Importar lista de reproducción existenteImportar nuevas pistas Importa archivos que no están en la base de datos todavía.Importando archivos...Importar...Información... Estadísticas de la bibliotecaRadio de InternetPlantilla inválidaConservar listas de reproducciónIconos grandesError de Last.FMLast.fmError de bibliotecaLigeraEnlaceEnlazar ArchivoEnlazar archivo de: %s a:Enlazar...UbicaciónUbicación:MinúsculaExtensión en minúsculaMagenta:ManualMediaImágenes medianasMenú Color de texto del menúFecha ModificadaModificado desde la última importación Solamente releer la etiqueta cuando el archivo ha sido modificado.Mover abajoMover ArchivoMover arribaMover archivo de: %s a:Mover...Biblioteca MusicalInformación de la biblioteca de músicaNombreRed no alcanzable.Nueva estación de radio de InternetNueva lista de reproducción... Crear nueva lista de reproducción.Nueva lista de reproducciónNueva lista de reproducción... Crear nueva lista de reproducciónNueva estación de radio... Crear nueva lista de reproducciónNueva estación... Nuevas Pistas:Nuevo directorio...SiguienteSiguiente Reproducir siguiente pista Reproducir siguiente pista.Pista posteriorSiguiente Pista Ctrl-] Reproducir pista anterior.Sin cambiosNinguna pista fue actualizada. ¿Sigues queriendo escribir las etiquetas para las pistas seleccionadas?No.NormalNormal Color de texto normalImágenes normalesApagadoOops. Error de base de datosAbrir ubicación de la carpeta Abrir ubicación de la carpeta.Opciones:¿Sobrescribir archivo?Sobreescribir predefinicióndA&nteriorAnalizar configuraciónAnalizar información de:Contraseña:PausarPausar Pausar Pausar reproducciónPausar reproducciónPausar reproducción.ReproducirReproducir Ctrl-P Iniciar reproducción.Reproducir Empezar reproducción Empezar reproducciónReproducir medioReproducir medio… Reproducir medioReproducciónError de reproducciónControles del reproductorReproduciendo Color de la pista en reproducciónPor favor, introduce el nombre de la predefinición:Por favor, especifique un archivo o url a reproducir:Por favor, espera. Esto puede tomar un tiempo.PreamplificadorPreferenciasPreferenciasLa predefinición %s ya existe. ¿Quieres sobrescribirla?Nombre de predefiniciónPredefinidos:Previsualizar imágenesAnteriorPrevia Reproducir pista previa Reproducir pista previa.Pista anteriorPista anterior Ctrl-[ Reproducir pista siguiente.ColaSalirRe&emplazar TodosError de lecturaSolo LecturaListo.Eliminar Eliminar.¿Eliminar álbum?Eliminar todas las pistas Eliminar todas las pistas de la biblioteca¿Eliminar artista?Eliminar archivos de audio...¿Suprimir archivos de audio?¿Eliminar género?¿Eliminar estación(es) de radio de Internet de la biblioteca?¿Eliminar estación(es) de radio de Internet?Eliminar lista de reproducción¿Eliminar pista(s)?¿Eliminar todas las pistas de la biblioteca de música?¿Eliminar pista(s) de la biblioteca?¿Eliminar pista(s) de la lista de reproducción?Eliminar pistas encontradas en la carpeta de la base de datos¿Eliminar pistas del álbum de la biblioteca?¿Eliminar pistas del álbum de la lista de reproducción?¿Eliminar pistas del artista de la biblioteca?¿Eliminar pistas del artista de la lista de reproducción?Eliminar pistas del discoEliminar pistas de la biblioteca de músicaEliminar pistas que hayan sido eliminadas del disco¿Eliminar pistas con género de la biblioteca?¿Eliminar pistas con género de la lista de reproducción?Eliminar... Supr Eliminar género de la biblioteca.Eliminar... Del Eliminar pistas asociadas de la biblioteca.Eliminar… Supr Eliminar pista(s) de la biblioteca.Eliminar… Supr Eliminar pistas(s) de la lista de reproducción.¿Renombrar archivos de audio?Renombrando archivos de audio...Repetir ARepetir A-BRepetir A-B Ctrl-T Repetir sección de pista.Repetir Todas las Pistas Ctrl-/ Repetir todas las pistas.Repetir Apagado Ctrl-, Repetir pista actual.Repetir Pista Ctrl-. Repetir pista actual.Reemplazar &con:Reemplazar espacios por guiones bajosReemplazar guiones bajos con espaciosGanancia de repetición:Recurso no disponible. Comprobar permisosInvertidoFilasB&uscar:Tasa de muestreoSaturación:ScrobbleAviso de seguridadSeleccionar ArchivoSeleccionar fuente normalSeleccionar todoSeleccionado Color de texto seleccionadoServicio:Sesión DBus no disponible. Todas las características que requieren sessionbus están desactivadas.Sesión bus no disponible. Todas las características que requieren dbus están desactivadas.Crear marcadorAjustar plantilla de exportación...Establecer número de pista en base a el orden de exploración.Configurar temporizadorSombra Color de la sombraMostrar &Géneros Ctrl-G Mostrar navegador de géneros.Mostrar &Fuentes Ctrl-S Mostrar navegador de orígenesMostrar navegadorMostrar Pantalla Completa F12 Cambiar a modo de pantalla completa.Mostrar iconos en el navegador de pistasMostrar etiquetasMostrar barra de estadoInformar sobre los cambios de pista Informar al demonio de notificaciones sobre cambios de pista.Mostrar icono de bandeja Mostrar icono en la bandeja de sistema.Mostrar carátula de la pista en reproducción Mostrar carátula de la pista en reproducciónMostrar las carátulas en el navegador de carátulas Mostrar las carátulas en el navegador de carátulasAleatorio Ctrl-RModo Aleatorio Alt-R Reproducir pistas en orden aleatorio.TamañoSaltar &TodosTemporizadorTemporizador Configurar temporizador.Dormir enIconos pequeñosOpciones de clasificaciónOrdenar porOrdenar por año del álbumOrdenOrígenes Pulsa para cambiar el orden Pulsa para cambiar el ordenEspecificar nombre de la nueva lista de reproducciónEspecifica url y descripción de la nueva estaciónIniciar reproducciónIniciar reproducción.EstaciónPararParar Ctrl-\ Parar reproducción.Parar Parar reproducción Parar reproducciónPara la reproducción en un cierto tiempoEstilo:Sincronizar carpeta... Sincronizar carpeta con música en la bibliotecaSincronizar operaciónSincronizar carpetaBandeja del sistemaEtiquetarLa plantilla puede contener rutas relativas o absolutas, variables de entorno y ~. Las rutas relativas están basadas en la localización del archivo original. La extensión del archivo queda automáticamente añadida. Las siguientes macros pueden ser usadas:Plantilla:Los siguientes archivos de audio serán eliminadosLos siguientes archivos de audio van a ser renombrados.La plantilla dada es inválida. El título de la pista %%T necesita ser especificado. Por favor, arregle el nombre de la plantilla en el panel de preferencias.DelgadaEsta versión de Goggles Music Manager no está soportada por Last-FM. Por favor, actualiza tu versión de GMM.DuraciónTítuloFormato de título:Consejo Color de consejosArribaTiempo total:PistaPistas:Tray Color del fondo de la bandejaApagar el motor de reproducción en stop.Encender el motor de reproducción al inicio. Para una inicialización más rápida, el motor de reproducción normalmente se enciende cuando la primera pista es reproducida. Para una inicialización más rápida, el motor de reproducción normalmente se enciende cuando la primera pista es reproducida.TipoNo se pudo copiar archivo: %s a: %s ¿Continuar con la operación?No se pudo crear el directorio %s. No se pudo borrar archivo: %s ¿Continuar con la operación?No se pudo inicializar el controlador de audioNo se pudo insertar la pista en la base de datosNo se pudo iniciar el navegador webNo se pudo enlazar archivo: %s a: %s ¿Continuar con la operación?No se pudo mover archivo: %s a: %s ¿Continuar con la operación?No se pudo abrir la base de datosNo se pudo eliminar álbum de la bibliotecaNo se pudo eliminar artista de la bibliotecaNo se pudo eliminar género de la bibliotecaNo se pudo eliminar la estación de la bibliotecaNo se pudo eliminar la pista de la bibliotecaNo se pudo renombrar el archivoNo se pudo renombrar el archivo: %s a:%sNo se pudo renombrar el archivo: %s a:%s ¿Continuar renombrando archivos?No se pudo actualizar pistaError desconocidoDispositivo desconocidoServidor desconocido.Sin títuloUn nivel arribaActualizar el nombre del archivoActualizar etiquetas en el archivo¿Actualizar etiquetas?Actualizar pistas existentes:Actualizar la url y descripción de la estaciónActualizando base de datos...UsuarioNombre de usuario:Valor:VerNormalización del volumenAdvertenciaVentanaDirectorio de trabajoAñoAmarillo:Tu colección de música consiste en...alt bg Color de fondo alternativobg Color de fondofg Color del primer planohoras yminutos....gogglesmm-0.12.7/po/pt.po0000644000175000001440000017402411663066766013737 0ustar sxjusers# Portuguese translation of gogglesmm package # Copyright (C) YEAR Sander Jansen # This file is distributed under the same license as the gogglesmm package. # Sérgio Marques , 2011 # msgid "" msgstr "" "Project-Id-Version: gogglesmm\n" "Report-Msgid-Bugs-To: s.jansen@gmail.com\n" "POT-Creation-Date: 2011-02-09 23:26-0600\n" "PO-Revision-Date: 2011-11-16 22:22-0000\n" "Last-Translator: Sérgio Marques \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: Portugal\n" #: src/GMAbout.cpp:136 #: src/GMDatabaseSource.cpp:218 #: src/GMDatabaseSource.cpp:2215 #: src/GMPreferencesDialog.cpp:551 msgid "&Close" msgstr "Fe&char" #: src/GMColumnDialog.cpp:204 msgid "Configure Columns" msgstr "Configurar colunas" #: src/GMColumnDialog.cpp:207 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:168 msgid "&Accept" msgstr "&Aceitar" #: src/GMColumnDialog.cpp:208 #: src/GMDatabaseSource.cpp:98 #: src/GMDatabaseSource.cpp:1274 #: src/GMDatabaseSource.cpp:1704 #: src/GMDatabaseSource.cpp:1804 #: src/GMDatabaseSource.cpp:1878 #: src/GMDatabaseSource.cpp:2121 #: src/GMDatabaseSource.cpp:2182 #: src/GMImportDialog.cpp:175 #: src/GMImportDialog.cpp:563 #: src/GMPlayListSource.cpp:281 #: src/GMPlayListSource.cpp:410 #: src/GMSearch.cpp:572 #: src/GMStreamSource.cpp:169 #: src/GMStreamSource.cpp:206 #: src/GMStreamSource.cpp:271 #: src/GMWindow.cpp:1198 #: src/GMWindow.cpp:1247 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:107 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:118 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:123 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:129 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:135 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:142 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:169 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:135 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:205 #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:113 msgid "&Cancel" msgstr "&Cancelar" #: src/GMColumnDialog.cpp:212 msgid "" "Choose the order of information to appear\n" "in the track list." msgstr "" "Escolha a ordem das informações\n" "a exibir na lista de faixas." #: src/GMColumnDialog.cpp:218 msgid "Move Up" msgstr "Para cima" #: src/GMColumnDialog.cpp:219 msgid "Move Down" msgstr "Para baixo" #: src/GMDatabaseSource.cpp:52 msgid "Invalid Template" msgstr "Modelo inválido" #: src/GMDatabaseSource.cpp:52 #, c-format msgid "" "The provided template is invalid. The track title %%T needs to be specified.\n" "Please fix the filename template in the preference panel." msgstr "" "O modelo indicado é inválido. Deve indicar %%T como título da faixa.\n" "Corrija o nome do modelo no painel de preferências." #: src/GMDatabaseSource.cpp:72 #: src/GMTrackDatabase.cpp:193 msgid "Database Error" msgstr "Erro na base de dados" #: src/GMDatabaseSource.cpp:72 msgid "Oops. Database Error" msgstr "Oops. Erro na base de dados" #: src/GMDatabaseSource.cpp:87 msgid "No changes" msgstr "Sem alterações" #: src/GMDatabaseSource.cpp:87 msgid "Filenames did not require any changes" msgstr "Os nomes não necessitam de ser alterados" #: src/GMDatabaseSource.cpp:94 msgid "Rename Audio Files?" msgstr "Mudar nome dos ficheiros?" #: src/GMDatabaseSource.cpp:95 msgid "Renaming Audio Files…" msgstr "A mudar nome dos ficheiros..." #: src/GMDatabaseSource.cpp:95 msgid "The following audio files are going to be renamed" msgstr "O nome dos seguintes ficheiros vai ser alterado:" #: src/GMDatabaseSource.cpp:97 msgid "&Rename" msgstr "Muda&r nome" #: src/GMDatabaseSource.cpp:121 #: src/GMDatabaseSource.cpp:125 msgid "Unable to rename file" msgstr "Incapaz de mudar o nome" #: src/GMDatabaseSource.cpp:121 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s\n" "Continue renaming files?" msgstr "" "Incapaz de mudar o nome de:\n" "%s\n" "\n" "para: %s\n" "Continuar operação?" #: src/GMDatabaseSource.cpp:125 #, c-format msgid "" "Unable to rename:\n" "%s\n" "\n" "to:%s" msgstr "" "Incapaz de mudar o nome de:\n" "%s\n" "\n" "para: %s" #: src/GMDatabaseSource.cpp:160 #: src/GMImportDialog.cpp:534 msgid "Filename Template" msgstr "Nome do ficheiro modelo" #: src/GMDatabaseSource.cpp:177 msgid "" "Template may contain absolute or relative path, environment variables\n" "and ~. Relative paths are based on the location of the original file. The\n" "file extension gets automatically added. The following macros\n" "may be used:" msgstr "" "Os modelos podem conter caminhos absolutos ou relativos, variáveis de\n" "ambiente e ~. Os caminhos relativos têm como base o local do ficheiro.\n" "A extensão de ficheiro é adicionada automaticamente. Pode utilizar\n" "as seguintes macros:" #: src/GMDatabaseSource.cpp:178 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name\n" "%y - year %d - disc number\n" "%N - track number (2 digits) %n - track number \n" "%G - genre" msgstr "" "%T - título %A - album name\n" "%P - artista do álbum %p - artista da faixa\n" "%y - ano %d - disc number\n" "%N - n.º da faixa (2 dígitos) %n - n.º da faixa\n" "%G - género" #: src/GMDatabaseSource.cpp:185 msgid "Conditions may be used as well:" msgstr "Também pode utilizar estas condições:" #: src/GMDatabaseSource.cpp:186 msgid "" "?c - display a if c is not empty else display b.\n" "?c - display c if not empty\n" msgstr "" "?c - exibe \"a\" se \"c\" não for vazio, senão exibe \"b\".\n" "?c - exibe \"c\" se não vazio\n" #: src/GMDatabaseSource.cpp:195 #: src/GMDatabaseSource.cpp:1815 #: src/GMImportDialog.cpp:546 msgid "Template:" msgstr "Modelo:" #: src/GMDatabaseSource.cpp:199 #: src/GMDatabaseSource.cpp:1819 msgid "Encoding:" msgstr "Codificação:" #: src/GMDatabaseSource.cpp:205 msgid "Exclude:" msgstr "Exclusão:" #: src/GMDatabaseSource.cpp:209 #: src/GMDatabaseSource.cpp:1825 msgid "Options:" msgstr "Opções:" #: src/GMDatabaseSource.cpp:210 #: src/GMDatabaseSource.cpp:1826 msgid "Replace spaces with underscores" msgstr "Substituir espaços por \"underscores\"" #: src/GMDatabaseSource.cpp:212 #: src/GMDatabaseSource.cpp:1828 msgid "Lower case" msgstr "Minúsculas" #: src/GMDatabaseSource.cpp:214 #: src/GMDatabaseSource.cpp:1830 msgid "Lower case extension" msgstr "Extensão de minúsculas" #: src/GMDatabaseSource.cpp:341 #: src/GMStreamSource.cpp:63 msgid "No." msgstr "N.º" #: src/GMDatabaseSource.cpp:342 msgid "Queue" msgstr "Fila" #: src/GMDatabaseSource.cpp:343 #: src/GMDatabaseSource.cpp:1391 #: src/GMTrackView.cpp:238 msgid "Title" msgstr "Título" #: src/GMDatabaseSource.cpp:344 #: src/GMDatabaseSource.cpp:1396 #: src/GMTrackView.cpp:239 msgid "Artist" msgstr "Artista" #: src/GMDatabaseSource.cpp:345 #: src/GMDatabaseSource.cpp:1397 msgid "Album Artist" msgstr "Artista do álbum" #: src/GMDatabaseSource.cpp:346 #: src/GMDatabaseSource.cpp:1405 #: src/GMPreferencesDialog.cpp:540 #: src/GMTrackView.cpp:240 msgid "Album" msgstr "Álbum" #: src/GMDatabaseSource.cpp:347 #: src/GMDatabaseSource.cpp:1364 #: src/GMDatabaseSource.cpp:1375 #: src/GMDatabaseSource.cpp:1381 msgid "Disc" msgstr "Disco" #: src/GMDatabaseSource.cpp:348 #: src/GMDatabaseSource.cpp:1408 #: src/GMStreamSource.cpp:66 #: src/GMStreamSource.cpp:177 #: src/GMStreamSource.cpp:216 #: src/GMTrackView.cpp:241 msgid "Genre" msgstr "Género" #: src/GMDatabaseSource.cpp:349 #: src/GMDatabaseSource.cpp:1369 #: src/GMDatabaseSource.cpp:1387 msgid "Year" msgstr "Ano" #: src/GMDatabaseSource.cpp:350 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:730 msgid "Time" msgstr "Duração" #: src/GMDatabaseSource.cpp:490 msgid "Remove…\tDel\tRemove Genre from Library." msgstr "Remover…\tDel\tRemover género da coleção." #: src/GMDatabaseSource.cpp:496 #: src/GMDatabaseSource.cpp:505 #: src/GMPlayListSource.cpp:104 #: src/GMPlayListSource.cpp:110 msgid "Copy\tCtrl-C\tCopy associated tracks to the clipboard." msgstr "Copiar\tCtrl-C\tCopiar faixas relacionadas para a área de transferência" #: src/GMDatabaseSource.cpp:499 #: src/GMDatabaseSource.cpp:508 msgid "Remove…\tDel\tRemove associated tracks from library." msgstr "Remover…\tDel\tRemover da coleção as faixas relacionadas" #: src/GMDatabaseSource.cpp:513 #: src/GMPlayListSource.cpp:116 msgid "Edit…\tF2\tEdit Track Information." msgstr "Editar…\tF2\tEditar informações da faixa" #: src/GMDatabaseSource.cpp:514 #: src/GMPlayListSource.cpp:117 msgid "Copy\tCtrl-C\tCopy track(s) to clipboard." msgstr "Copiar\tCtrl-C\tCopiar faixa(s) para a área de transferência" #: src/GMDatabaseSource.cpp:518 #: src/GMPlayListSource.cpp:120 msgid "Open Folder Location\t\tOpen Folder Location." msgstr "Abrir local da pasta\t\tAbrir local da pasta" #: src/GMDatabaseSource.cpp:523 msgid "Remove…\tDel\tRemove track(s) from library." msgstr "Remover…\tDel\tRemover faixa(s) da coleção" #: src/GMDatabaseSource.cpp:537 msgid "New Play List…\t\tCreate a new play list." msgstr "Nova lista de reprodução…\t\tCriar nova lista de reprodução" #: src/GMDatabaseSource.cpp:539 #: src/GMPlayListSource.cpp:163 msgid "Export…" msgstr "Exportar…" #: src/GMDatabaseSource.cpp:540 msgid "Information…\t\tLibrary Statistics" msgstr "Informações…\t\tEstatísticas da coleção" #: src/GMDatabaseSource.cpp:542 msgid "Remove All Tracks\t\tRemove all tracks from the library" msgstr "Remover todas as faixas\t\tRemover todas as faixas da coleção" #: src/GMDatabaseSource.cpp:1272 msgid "Edit Track Information" msgstr "Editar informações da faixa" #: src/GMDatabaseSource.cpp:1275 #: src/GMPlayListSource.cpp:409 #: src/GMStreamSource.cpp:205 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:128 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:143 msgid "&Save" msgstr "&Gravar" #: src/GMDatabaseSource.cpp:1315 msgid "&Tag" msgstr "De&talhes" #: src/GMDatabaseSource.cpp:1320 msgid "&Properties" msgstr "&Propriedades" #: src/GMDatabaseSource.cpp:1325 #: src/GMImportDialog.cpp:525 msgid "Filename" msgstr "Nome do ficheiro" #: src/GMDatabaseSource.cpp:1329 #: ../../../fox-1.6.37/src/FXFileList.cpp:193 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:728 msgid "Type" msgstr "Tipo" #: src/GMDatabaseSource.cpp:1333 #: ../../../fox-1.6.37/src/FXFileList.cpp:194 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:729 msgid "Size" msgstr "Tamanho" #: src/GMDatabaseSource.cpp:1341 #: src/GMStreamSource.cpp:65 msgid "Bitrate" msgstr "Qualidade" #: src/GMDatabaseSource.cpp:1345 msgid "Samplerate" msgstr "Frequência" #: src/GMDatabaseSource.cpp:1349 msgid "Channels" msgstr "Canais" #: src/GMDatabaseSource.cpp:1358 #: src/GMPreferencesDialog.cpp:539 msgid "Track" msgstr "Faixa" #: src/GMDatabaseSource.cpp:1403 msgid "\tSeparate Artists" msgstr "" #: src/GMDatabaseSource.cpp:1403 msgid "\tShared Artists" msgstr "" #: src/GMDatabaseSource.cpp:1416 msgid "Auto track number. Offset:" msgstr "N.º de faixa automático. Inicia:" #: src/GMDatabaseSource.cpp:1425 msgid "Update Tag in File" msgstr "Atualizar detalhes no ficheiro" #: src/GMDatabaseSource.cpp:1430 msgid "Update Filename" msgstr "Atualizar nome de ficheiro" #: src/GMDatabaseSource.cpp:1431 msgid "Set export template…" msgstr "Definir modelo..." #: src/GMDatabaseSource.cpp:1645 msgid "Update Tags?" msgstr "Atualizar detalhes?" #: src/GMDatabaseSource.cpp:1645 msgid "" "No tracks were updated.\n" "Would you still like to write the tags for the selected tracks?" msgstr "" "Nenhuma faixa foi alterada.\n" "Ainda assim, pretende gravar os detalhes das faixas selecionadas?" #: src/GMDatabaseSource.cpp:1700 msgid "Remove Audio Files?" msgstr "Remover ficheiros áudio?" #: src/GMDatabaseSource.cpp:1701 msgid "Remove Audio Files..." msgstr "Remover ficheiros áudio..." #: src/GMDatabaseSource.cpp:1701 msgid "The following audio files are going to be removed" msgstr "Estes ficheiros áudio vão ser removidos" #: src/GMDatabaseSource.cpp:1703 #: src/GMDatabaseSource.cpp:1877 #: src/GMPlayListSource.cpp:280 #: src/GMStreamSource.cpp:270 msgid "&Remove" msgstr "&Remover" #: src/GMDatabaseSource.cpp:1729 msgid "Export Main Library" msgstr "Exportar coleção principal" #: src/GMDatabaseSource.cpp:1731 msgid "Export Play List" msgstr "Exportar lista de reprodução" #: src/GMDatabaseSource.cpp:1744 msgid "Overwrite File?" msgstr "Substituir ficheiro?" #: src/GMDatabaseSource.cpp:1744 msgid "File already exists. Would you like to overwrite it?" msgstr "O ficheiro já existe. Pretende substituir?" #: src/GMDatabaseSource.cpp:1784 msgid "Export Genre" msgstr "Exportar por género" #: src/GMDatabaseSource.cpp:1785 msgid "Export tracks with genre to destination directory." msgstr "Exportar faixas deste género para o diretório" #: src/GMDatabaseSource.cpp:1787 msgid "Export Artists" msgstr "Exportar artistas" #: src/GMDatabaseSource.cpp:1788 msgid "Export tracks from artist to destination directory." msgstr "Exportar faixas deste artista para o diretório" #: src/GMDatabaseSource.cpp:1790 msgid "Export Albums" msgstr "Exportar álbuns" #: src/GMDatabaseSource.cpp:1791 msgid "Export tracks from album to destination directory." msgstr "Exportar faixas deste álbum para o diretório" #: src/GMDatabaseSource.cpp:1793 msgid "Export Tracks" msgstr "Exportar faixas" #: src/GMDatabaseSource.cpp:1794 msgid "Export tracks to destination directory." msgstr "Exportar faixas para o diretório" #: src/GMDatabaseSource.cpp:1803 msgid "&Export" msgstr "&Exportar" #: src/GMDatabaseSource.cpp:1853 #: src/GMPlayListSource.cpp:261 msgid "Remove Genre?" msgstr "Remover género?" #: src/GMDatabaseSource.cpp:1854 msgid "Remove tracks with genre from library?" msgstr "Remover da coleção as faixas deste género?" #: src/GMDatabaseSource.cpp:1858 #: src/GMPlayListSource.cpp:264 msgid "Remove Artist?" msgstr "Remover artista?" #: src/GMDatabaseSource.cpp:1859 msgid "Remove tracks from artist from library?" msgstr "Remover da coleção as faixas deste artista?" #: src/GMDatabaseSource.cpp:1863 #: src/GMPlayListSource.cpp:267 msgid "Remove Album?" msgstr "Remover álbum?" #: src/GMDatabaseSource.cpp:1864 msgid "Remove tracks from album from library?" msgstr "Remover este álbum da coleção?" #: src/GMDatabaseSource.cpp:1868 #: src/GMPlayListSource.cpp:270 msgid "Remove Track(s)?" msgstr "Remover faixa(s)?" #: src/GMDatabaseSource.cpp:1869 msgid "Remove track(s) from library?" msgstr "Remover faixa(s) da coleção?" #: src/GMDatabaseSource.cpp:1881 #: src/GMPlayListSource.cpp:285 msgid "Remove tracks from disk" msgstr "Remover faixas do disco rígido" #: src/GMDatabaseSource.cpp:1895 #: src/GMDatabaseSource.cpp:1899 #: src/GMDatabaseSource.cpp:1903 #: src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 #: src/GMStreamSource.cpp:280 msgid "Library Error" msgstr "Erro na coleção" #: src/GMDatabaseSource.cpp:1895 msgid "Unable to remove genre from the library" msgstr "Incapaz de remover o género" #: src/GMDatabaseSource.cpp:1899 msgid "Unable to remove artist from the library" msgstr "Incapaz de remover o artista" #: src/GMDatabaseSource.cpp:1903 msgid "Unable to remove album from the library" msgstr "Incapaz de remover o álbum" #: src/GMDatabaseSource.cpp:1907 #: src/GMPlayListSource.cpp:308 msgid "Unable to remove track from the library." msgstr "Incapaz de remover a(s) faixa(s)" #: src/GMDatabaseSource.cpp:2117 #: src/GMDatabaseSource.cpp:2118 msgid "Create Playlist" msgstr "Criar lista de reprodução" #: src/GMDatabaseSource.cpp:2118 msgid "Specify name of the new playlist" msgstr "Indique o nome da nova lista" #: src/GMDatabaseSource.cpp:2120 msgid "&Create" msgstr "C&riar" #: src/GMDatabaseSource.cpp:2125 #: src/GMPlayListSource.cpp:415 #: ../../../fox-1.6.37/src/FXFileList.cpp:192 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:727 msgid "Name" msgstr "Nome" #: src/GMDatabaseSource.cpp:2127 msgid "New Playlist" msgstr "Nova lista de reprodução" #: src/GMDatabaseSource.cpp:2178 #: src/GMDatabaseSource.cpp:2179 msgid "Clear Music Library?" msgstr "Apagar coleção?" #: src/GMDatabaseSource.cpp:2179 msgid "Remove all tracks from the music library?" msgstr "Remover todas as faixas da coleção?" #: src/GMDatabaseSource.cpp:2181 msgid "&Remove All" msgstr "&Remover tudo" #: src/GMDatabaseSource.cpp:2185 msgid "Keep play lists" msgstr "Manter listas de reprodução" #: src/GMDatabaseSource.cpp:2212 #: src/GMDatabaseSource.cpp:2213 msgid "Music Library Information" msgstr "Informações da coleção" #: src/GMDatabaseSource.cpp:2213 msgid "You music collection consists of…" msgstr "A sua coleção possui..." #: src/GMDatabaseSource.cpp:2221 msgid "Tracks:" msgstr "Faixas:" #: src/GMDatabaseSource.cpp:2226 msgid "Artists:" msgstr "Artistas:" #: src/GMDatabaseSource.cpp:2230 msgid "Albums:" msgstr "Álbums:" #: src/GMDatabaseSource.cpp:2234 msgid "Total Time:" msgstr "Tempo total:" #: src/GMEQDialog.cpp:96 msgid "Equalizer" msgstr "Equalizador" #: src/GMEQDialog.cpp:135 msgid "Equalizer:" msgstr "Equalizador:" #: src/GMEQDialog.cpp:137 msgid "\tSave" msgstr "\tGravar" #: src/GMEQDialog.cpp:138 msgid "\tReset" msgstr "\tRepor" #: src/GMEQDialog.cpp:139 msgid "\tRemove" msgstr "\tRemover" #: src/GMEQDialog.cpp:172 msgid "Pre-amp" msgstr "Amplificador" #: src/GMEQDialog.cpp:244 #: src/GMEQDialog.cpp:254 msgid "Disabled" msgstr "Inativo" #: src/GMEQDialog.cpp:247 #: src/GMEQDialog.cpp:299 msgid "Manual" msgstr "Manual" #: src/GMEQDialog.cpp:314 msgid "Delete Preset" msgstr "Eliminar pré-ajuste" #: src/GMEQDialog.cpp:314 #, c-format msgid "Are you sure you want to delete %s preset?" msgstr "Tem a certeza de que quer eliminar %s?" #: src/GMEQDialog.cpp:334 msgid "Preset Name" msgstr "Nome" #: src/GMEQDialog.cpp:334 msgid "Please enter preset name:" msgstr "Indique o nome do pré-ajuste" #: src/GMEQDialog.cpp:338 msgid "Overwrite Preset" msgstr "Substituir pré-ajuste" #: src/GMEQDialog.cpp:338 #, c-format msgid "Preset %s already exists. Would you like to overwrite it?" msgstr "%s já existe. Pretende substituir o pré-ajuste?" #: src/GMFontDialog.cpp:209 msgid "Ultra Condensed" msgstr "Ultra condensada" #: src/GMFontDialog.cpp:210 msgid "Extra Condensed" msgstr "Extra condensada" #: src/GMFontDialog.cpp:211 msgid "Condensed" msgstr "Condensada" #: src/GMFontDialog.cpp:212 msgid "Semi Condensed" msgstr "Pouco condensada" #: src/GMFontDialog.cpp:214 msgid "Semi Expanded" msgstr "Pouco expandida" #: src/GMFontDialog.cpp:215 msgid "Expanded" msgstr "Expandida" #: src/GMFontDialog.cpp:216 msgid "Extra Expanded" msgstr "Extra expandida" #: src/GMFontDialog.cpp:217 msgid "Ultra Expanded" msgstr "Ultra expandida" #: src/GMFontDialog.cpp:224 #: src/GMPreferencesDialog.cpp:1223 msgid "Thin" msgstr "Estreita" #: src/GMFontDialog.cpp:225 #: src/GMPreferencesDialog.cpp:1224 msgid "Extra Light" msgstr "Extra suave" #: src/GMFontDialog.cpp:226 #: src/GMPreferencesDialog.cpp:1225 msgid "Light" msgstr "Suave" #: src/GMFontDialog.cpp:228 #: src/GMPreferencesDialog.cpp:1227 msgid "Medium" msgstr "Média" #: src/GMFontDialog.cpp:229 #: src/GMPreferencesDialog.cpp:1228 msgid "Demibold" msgstr "Pouco negrito" #: src/GMFontDialog.cpp:230 #: src/GMPreferencesDialog.cpp:1229 msgid "Bold" msgstr "Negrito" #: src/GMFontDialog.cpp:231 #: src/GMPreferencesDialog.cpp:1230 msgid "Extra Bold" msgstr "Extra negrito" #: src/GMFontDialog.cpp:232 #: src/GMPreferencesDialog.cpp:1231 msgid "Heavy" msgstr "Carregada" #: src/GMFontDialog.cpp:239 msgid "Reverse Oblique" msgstr "Oblíqua invertida" #: src/GMFontDialog.cpp:240 msgid "Reverse Italic" msgstr "Ítálico invertido" #: src/GMFontDialog.cpp:242 msgid "Italic" msgstr "Ítalico" #: src/GMFontDialog.cpp:243 msgid "Oblique" msgstr "Oblíqua" #: src/GMFontDialog.cpp:265 msgid "Normal" msgstr "Normal" #: src/GMImportDialog.cpp:91 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:137 msgid "&Directory:" msgstr "Dire&tório:" #: src/GMImportDialog.cpp:166 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:196 msgid "&File Name:" msgstr "Nome do &ficheiro:" #: src/GMImportDialog.cpp:168 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:102 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:106 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:134 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:198 msgid "&OK" msgstr "&OK" #: src/GMImportDialog.cpp:170 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:200 msgid "File F&ilter:" msgstr "F&iltro:" #: src/GMImportDialog.cpp:174 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:204 msgid "Read Only" msgstr "Só leitura" #: src/GMImportDialog.cpp:179 #: src/GMSearch.cpp:565 #: src/GMSearch.cpp:647 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:208 msgid "Directory:" msgstr "Diretório:" #: src/GMImportDialog.cpp:186 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:228 msgid "&Set bookmark\t\tBookmark current directory." msgstr "&Definir marcadort\tMarcar diretório atual" #: src/GMImportDialog.cpp:187 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:229 msgid "&Clear bookmarks\t\tClear bookmarks." msgstr "Apagar mar&cadores\t\tApagar marcadores" #: src/GMImportDialog.cpp:203 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:244 msgid "\tGo up one directory\tMove up to higher directory." msgstr "\tSubir um diretório\tIr para o diretório superior" #: src/GMImportDialog.cpp:204 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:245 msgid "\tGo to home directory\tBack to home directory." msgstr "\tIr para o diretório pessoal\tIr para o diretório pessoal" #: src/GMImportDialog.cpp:205 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:246 msgid "\tGo to work directory\tBack to working directory." msgstr "\tIr para o diretório de trabalho\tIr para o diretório de trabalho" #: src/GMImportDialog.cpp:206 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:247 msgid "\tBookmarks\tVisit bookmarked directories." msgstr "\tMarcadores\tVer diretórios marcados" #: src/GMImportDialog.cpp:209 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:250 msgid "\tCreate new directory\tCreate new directory." msgstr "\tCriar novo diretório\tCriar novo diretório" #: src/GMImportDialog.cpp:210 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:251 msgid "\tShow list\tDisplay directory with small icons." msgstr "\tMostrar em lista\tExibir diretório com ícones pequenos" #: src/GMImportDialog.cpp:211 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:252 msgid "\tShow icons\tDisplay directory with big icons." msgstr "\tMostrar ícones\tExibir diretório com ícones grandes" #: src/GMImportDialog.cpp:212 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:253 msgid "\tShow details\tDisplay detailed directory listing." msgstr "\tMostrar detalhes\tExibir detalhes do diretório" #: src/GMImportDialog.cpp:213 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tShow hidden files\tShow hidden files and directories." msgstr "\tMostrar ficheiros\tMostrar diretórios/ficheiros ocultos" #: src/GMImportDialog.cpp:213 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:254 msgid "\tHide Hidden Files\tHide hidden files and directories." msgstr "\tOcultar ficheiros\tNão mostrar diretórios/ficheiros ocultos" #: src/GMImportDialog.cpp:412 msgid "Synchronize Folder" msgstr "Sincronizar pasta" #: src/GMImportDialog.cpp:414 msgid "Import Playlist" msgstr "Importar lista de reprodução" #: src/GMImportDialog.cpp:416 msgid "Import Music" msgstr "Importar músicas" #: src/GMImportDialog.cpp:448 msgid "&File(s)" msgstr "&Ficheiro(s)" #: src/GMImportDialog.cpp:475 msgid "&Directory" msgstr "&Diretório" #: src/GMImportDialog.cpp:478 msgid "Exclude Filter\tFilter out directories and/or files based on pattern" msgstr "Exclusão\tFiltrar diretórios e/ou ficheiros com base num padrão" #: src/GMImportDialog.cpp:481 msgid "Folders:" msgstr "Pastas:" #: src/GMImportDialog.cpp:483 msgid "Files:" msgstr "Ficheiros:" #: src/GMImportDialog.cpp:499 #: src/GMImportDialog.cpp:560 msgid "&Sync" msgstr "&Sincronizar" #: src/GMImportDialog.cpp:501 msgid "Sync Operation" msgstr "Sincronização" #: src/GMImportDialog.cpp:504 msgid "Import new tracks\tImports files not yet in the database." msgstr "Importar faixas\tImportar ficheiros não existentes na base de dados" #: src/GMImportDialog.cpp:505 msgid "Remove tracks that have been deleted from disk" msgstr "Remover faixas que foram eliminadas do disco" #: src/GMImportDialog.cpp:507 msgid "Update existing tracks:" msgstr "Atualizar faixas existentes:" #: src/GMImportDialog.cpp:508 msgid "Modified since last import\tOnly reread the tag when the file has been modified." msgstr "Se modificadas desde a última importação\tReanalisar detalhes dos ficheiros modificados" #: src/GMImportDialog.cpp:510 msgid "All\tAlways read the tags" msgstr "Sempre\tReanalisar todos os detalhes" #: src/GMImportDialog.cpp:511 msgid "Remove tracks found in folder from database" msgstr "Remover da base de dados as faixas encontradas na pasta" #: src/GMImportDialog.cpp:514 msgid "&Track" msgstr "Fai&xa" #: src/GMImportDialog.cpp:517 msgid "Parse Settings" msgstr "Definições" #: src/GMImportDialog.cpp:521 msgid "Parse info from:" msgstr "Analisar de:" #: src/GMImportDialog.cpp:524 msgid "Tag" msgstr "Detalhes" #: src/GMImportDialog.cpp:526 msgid "Both" msgstr "Ambos" #: src/GMImportDialog.cpp:528 msgid "Default value:" msgstr "Valor pré-definido:" #: src/GMImportDialog.cpp:532 msgid "Set track number based on scan order." msgstr "Definir número da faixa com base na ordem" #: src/GMImportDialog.cpp:537 msgid "" "%T - title %A - album name\n" "%P - album artist name %p - track artist name \n" "%N - track number %G - genre" msgstr "" "%T - titulo %A - álbum\n" "%P - artista do álbum %p - artista da faixa\n" "%N - n.º da faixa %G - género" #: src/GMImportDialog.cpp:549 msgid "Replace underscores with spaces" msgstr "Substituir \"underscores\" por espaços" #: src/GMImportDialog.cpp:562 msgid "&Import" msgstr "&Importar" #: src/GMPlayer.cpp:212 msgid "Unable to initialize audio driver." msgstr "Incapaz de iniciar o sistema de som" #: src/GMPlayer.cpp:714 msgid "Unknown host." msgstr "Servidor desconhecido" #: src/GMPlayer.cpp:715 msgid "Unknown device" msgstr "Dispositivo desconhecido" #: src/GMPlayer.cpp:716 msgid "Network not reachable." msgstr "Incapaz de ligar à rede" #: src/GMPlayer.cpp:717 msgid "Audio output unavailable." msgstr "Sistema de som não disponível" #: src/GMPlayer.cpp:718 msgid "Connection Refused." msgstr "Ligação recusada" #: src/GMPlayer.cpp:719 msgid "File not found." msgstr "Ficheiro não encontrado" #: src/GMPlayer.cpp:720 msgid "Resource not accessible. Check permissions" msgstr "Incapaz de aceder ao recurso. Veja as permissões" #: src/GMPlayer.cpp:721 msgid "Read Error" msgstr "Erro de leitura" #: src/GMPlayer.cpp:722 msgid "Error while loading library/plugin" msgstr "Erro ao carregar coleção/\"plug-in\"" #: src/GMPlayer.cpp:723 msgid "Warning" msgstr "Aviso" #: src/GMPlayer.cpp:724 msgid "Security Warning" msgstr "Aviso de segurança" #: src/GMPlayer.cpp:725 msgid "Unknown Error" msgstr "Erro desconhecido" #: src/GMPlayer.cpp:761 msgid "Error" msgstr "Erro" #: src/GMPlayerManager.cpp:439 #, c-format msgid "Unable to create directory %s\n" msgstr "Incapaz de criar o diretório %s\n" #: src/GMPlayerManager.cpp:612 msgid "" "For some reason the FOX library was compiled without PNG support.\n" "In order to show all icons, Goggles Music Manager requires PNG\n" "support in the FOX library. If you've compiled FOX yourself, most\n" "likely the libpng header files were not installed on your system." msgstr "" "Por alguma razão a biblioteca FOX foi compilada sem suporte a PNG.\n" "Para mostrar todos os ícones, o Goggles necessita do suporte a PNG\n" "disponibilizado pela biblioteca FOX. Se foi você que compilou o FOX,\n" "verifique se ficheiros libpng estão instalados." #: src/GMPlayerManager.cpp:623 msgid "Session bus not available. All features requiring dbus are disabled." msgstr "Canal de transmissão indisponível. Todas as funções Dbus estão inativas." #: src/GMPlayerManager.cpp:633 msgid "A DBus error occurred. All features requiring sessionbus are disabled." msgstr "Ocorreu um erro DBus. Todas as funções sessionbus estão inativas." #: src/GMPlayerManager.cpp:644 msgid "Session Bus not available. All features requiring sessionbus are disabled." msgstr "Bus de sessão indisponível. Todas as funções sessionbus estão inativas." #: src/GMPlayerManager.cpp:719 #: src/GMPreferencesDialog.cpp:594 msgid "Audio Device Error" msgstr "Erro de dispositivo" #: src/GMPlayerManager.cpp:1551 msgid "Last.FM Error" msgstr "Erro last.fm" #: src/GMPlayerManager.cpp:1558 msgid "Playback Error" msgstr "Erro de reprodução" #: src/GMPlayerManager.cpp:1708 #, c-format msgid "" "%s\n" "%s (%d)" msgstr "" "%s\n" "%s (%d)" #: src/GMPlayListSource.cpp:99 #: src/GMPlayListSource.cpp:105 #: src/GMPlayListSource.cpp:111 #: src/GMPlayListSource.cpp:121 msgid "Remove…\tDel\tRemove track(s) from play list." msgstr "Remover…\tDel\tRemover faixa(s) da lista de reprodução" #: src/GMPlayListSource.cpp:161 msgid "Edit…" msgstr "Editar…" #: src/GMPlayListSource.cpp:162 msgid "Import…" msgstr "Importar…" #: src/GMPlayListSource.cpp:164 msgid "Remove Playlist" msgstr "Remover lista de reprodução" #: src/GMPlayListSource.cpp:262 msgid "Remove tracks with genre from play list?" msgstr "Remover da lista de reprodução as faixas deste género?" #: src/GMPlayListSource.cpp:265 msgid "Remove tracks from artist from play list?" msgstr "Remover da lista de reprodução as faixas deste artista?" #: src/GMPlayListSource.cpp:268 msgid "Remove tracks from album from play list?" msgstr "Remover este álbum da lista de reprodução?" #: src/GMPlayListSource.cpp:271 msgid "Remove track(s) from play list?" msgstr "Remover faixa(s) da lista de reprodução?" #: src/GMPlayListSource.cpp:284 msgid "Remove tracks from music library" msgstr "Remover faixas da coleção" #: src/GMPlayListSource.cpp:406 #: src/GMPlayListSource.cpp:407 msgid "Edit Playlist" msgstr "Editar lista de reprodução" #: src/GMPlayListSource.cpp:407 msgid "Change playlist name" msgstr "Mudar nome da lista de reprodução" #: src/GMPlayListSource.cpp:432 msgid "Delete Play List?" msgstr "Eliminar lista de reprodução?" #: src/GMPlayListSource.cpp:432 msgid "Are you sure you want to delete the playlist?" msgstr "Tem a certeza de que quer eliminar a lista de reprodução?" #: src/GMPlayListSource.cpp:432 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:111 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:116 msgid "&Yes" msgstr "&Sim" #: src/GMPlayListSource.cpp:432 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:112 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:117 msgid "&No" msgstr "&Não" #: src/GMPreferencesDialog.cpp:252 msgid "Preferences" msgstr "Preferências" #: src/GMPreferencesDialog.cpp:286 msgid "&General" msgstr "&Geral" #: src/GMPreferencesDialog.cpp:289 msgid "Sort Options" msgstr "Opções de ordem" #: src/GMPreferencesDialog.cpp:293 msgid "Ignore leading words" msgstr "Ignorar as palavras" #: src/GMPreferencesDialog.cpp:296 msgid "Album Covers" msgstr "Capas de álbum" #: src/GMPreferencesDialog.cpp:299 msgid "Show album cover of playing track\tShow album cover of playing track" msgstr "Mostrar capa de álbum da faixa em reprodução\tMostrar capa de álbum da faixa em reprodução" #: src/GMPreferencesDialog.cpp:300 msgid "Show album covers in album browser\tShow album covers in album browser" msgstr "Mostrar capa de álbum no explorador de álbuns\tMostrar capa de álbum no explorador de álbuns" #: src/GMPreferencesDialog.cpp:302 msgid "System Tray" msgstr "Bandeja do sistema" #: src/GMPreferencesDialog.cpp:304 msgid "Show Tray Icon\tShow tray icon in the system tray." msgstr "Mostrar ícone na bandeja\tMostrar ícone na bandeja do sistema" #: src/GMPreferencesDialog.cpp:307 msgid "Show Track Change Notifications\tInform notification daemon of track changes." msgstr "Mostrar notificação de alteração de faixa\tMostrar notificações ao alterar de faixa" #: src/GMPreferencesDialog.cpp:311 msgid "Last.fm" msgstr "Last.fm" #: src/GMPreferencesDialog.cpp:315 msgid "" "This version of Goggles Music Manager is\n" "not supported by Last-FM. Please upgrade\n" "to a newer version of GMM." msgstr "" "A last.fm não possui suporte a esta versão\n" "do Goggles Music Manager.\n" "Deve atualizar o Goggles Music Manager. " #: src/GMPreferencesDialog.cpp:321 msgid "Service:" msgstr "Serviço:" #: src/GMPreferencesDialog.cpp:338 msgid "&Sign up…" msgstr "Iniciar &sessão..." #: src/GMPreferencesDialog.cpp:344 msgid "Username:" msgstr "Utilizador:" #: src/GMPreferencesDialog.cpp:346 msgid "Password:" msgstr "Senha:" #: src/GMPreferencesDialog.cpp:349 msgid "Scrobble" msgstr "\"Scrobble\"" #: src/GMPreferencesDialog.cpp:359 msgid "&Window" msgstr "&Janela" #: src/GMPreferencesDialog.cpp:362 msgid "Window" msgstr "Janela" #: src/GMPreferencesDialog.cpp:365 msgid "Close button minimizes to tray" msgstr "Botão \"Fechar\" minimiza para a bandeja" #: src/GMPreferencesDialog.cpp:366 msgid "Show Status Bar" msgstr "Mostrar barra de estado" #: src/GMPreferencesDialog.cpp:368 msgid "Show Icons in Track Browser" msgstr "Mostrar ícones no explorador de faixas" #: src/GMPreferencesDialog.cpp:370 msgid "Display playing track in title bar" msgstr "Mostrar nome da faixa atual na barra de título" #: src/GMPreferencesDialog.cpp:372 msgid "Player Controls" msgstr "Controlos" #: src/GMPreferencesDialog.cpp:376 msgid "Location:" msgstr "Localização:" #: src/GMPreferencesDialog.cpp:378 msgid "Top" msgstr "Em cima" #: src/GMPreferencesDialog.cpp:379 msgid "Bottom" msgstr "Em baixo" #: src/GMPreferencesDialog.cpp:387 msgid "Title Format:" msgstr "Formato do título:" #: src/GMPreferencesDialog.cpp:391 msgid "Style:" msgstr "Estilo" #: src/GMPreferencesDialog.cpp:392 msgid "Show Labels" msgstr "Mostrar texto" #: src/GMPreferencesDialog.cpp:395 msgid "Large Icons" msgstr "Ícones grandes" #: src/GMPreferencesDialog.cpp:399 msgid "A&ppearance" msgstr "As&peto" #: src/GMPreferencesDialog.cpp:402 msgid "Colors" msgstr "Cores" #: src/GMPreferencesDialog.cpp:409 msgid "fg\tForeground Color" msgstr "CF\tCor de fundo" #: src/GMPreferencesDialog.cpp:410 msgid "bg\tBackground Color" msgstr "CP\tCor principal" #: src/GMPreferencesDialog.cpp:411 msgid "alt bg\tAlternative Background Color" msgstr "CF ALT\tCor de fundo alternativa" #: src/GMPreferencesDialog.cpp:422 msgid "Normal\tNormal Text Color" msgstr "Normal\tCor de texto normal" #: src/GMPreferencesDialog.cpp:426 msgid "Base\tBase Color" msgstr "Base\tCor base" #: src/GMPreferencesDialog.cpp:429 msgid "Selected\tSelected Text Color" msgstr "Seleção\tCor do texto da seleção" #: src/GMPreferencesDialog.cpp:433 msgid "Menu\tMenu Base Color" msgstr "Menu\tCor do menu" #: src/GMPreferencesDialog.cpp:437 msgid "Menu\tMenu Text Color" msgstr "Menu\tCor do texto do menu" #: src/GMPreferencesDialog.cpp:441 msgid "Border\tBorder Color" msgstr "Contornos\tCor dos contornos" #: src/GMPreferencesDialog.cpp:445 msgid "Tooltip\tTooltip Color" msgstr "Dicas\tCor das dicas" #: src/GMPreferencesDialog.cpp:449 msgid "Hilite\tHilite Color" msgstr "Realce\tCor de realce" #: src/GMPreferencesDialog.cpp:456 msgid "Shadow\tShadow Color" msgstr "Sombra\tCor da sombra" #: src/GMPreferencesDialog.cpp:459 msgid "Playing\tPlaying Track Color" msgstr "Em reprodução\tCor da faixa em reprodução" #: src/GMPreferencesDialog.cpp:463 msgid "Tray\tTray Background Color" msgstr "Bandeja\tCor de fundo da bandeja" #: src/GMPreferencesDialog.cpp:473 msgid "Presets:" msgstr "Pré-ajustes:" #: src/GMPreferencesDialog.cpp:481 msgid "Font & Icons" msgstr "Letras e ícones" #: src/GMPreferencesDialog.cpp:487 msgid "Default Font" msgstr "Letra pré-definida" #: src/GMPreferencesDialog.cpp:489 msgid "Change…" msgstr "Alterar..." #: src/GMPreferencesDialog.cpp:490 msgid "Icons" msgstr "Ícones" #: src/GMPreferencesDialog.cpp:509 msgid "&Audio" msgstr "Á&udio" #: src/GMPreferencesDialog.cpp:512 msgid "Engine" msgstr "Sistema" #: src/GMPreferencesDialog.cpp:516 msgid "Audio Driver:" msgstr "Controlador:" #: src/GMPreferencesDialog.cpp:527 msgid "Close audio device on pause." msgstr "Fechar dispositivo ao pausar" #: src/GMPreferencesDialog.cpp:528 msgid "Turn off playback engine on stop." msgstr "Desligar sistema de reprodução ao parar" #: src/GMPreferencesDialog.cpp:529 msgid "Turn on playback engine on startup.\tFor faster startup, playback engine is normally started when first track is played.\tFor faster startup, playback engine is normally started when first track is played." msgstr "Ligar sistema de reprodução ao iniciar\tPara um início mais rápido, o sistema de som é iniciado ao reproduzir a primeira faixa\tPara um início mais rápido, o sistema de som é iniciado ao reproduzir a primeira faixa" #: src/GMPreferencesDialog.cpp:532 msgid "Playback" msgstr "Reprodução" #: src/GMPreferencesDialog.cpp:536 msgid "Replay Gain:" msgstr "Replay Gain:" #: src/GMPreferencesDialog.cpp:538 msgid "Off" msgstr "Desligado" #: src/GMPreferencesDialog.cpp:543 msgid "Gapless playback" msgstr "Reprodução Gapless" #: src/GMPreferencesDialog.cpp:544 msgid "Volume Normalization" msgstr "Normalização de volume" #: src/GMPreferencesDialog.cpp:594 #, c-format msgid "Failed to open requested audio driver: %s" msgstr "Falha ao carregar o controlador áudio: %s" #: src/GMPreferencesDialog.cpp:678 msgid "Current" msgstr "Atual" #: src/GMPreferencesDialog.cpp:696 msgid "Custom" msgstr "Personalizar" #: src/GMPreferencesDialog.cpp:769 #: src/GMPreferencesDialog.cpp:774 #: src/GMWindow.cpp:1133 #: src/GMWindow.cpp:1140 #: src/GMWindow.cpp:1147 #: src/GMWindow.cpp:1154 msgid "Unable to launch webbrowser" msgstr "Incapaz de iniciar o navegador web" #: src/GMPreferencesDialog.cpp:1172 msgid "Select Normal Font" msgstr "Selecione o tipo de letra" #: src/GMRemote.cpp:295 msgid "&Next" msgstr "Segui&nte" #: src/GMRemote.cpp:296 msgid "P&revious" msgstr "Ante&rior" #: src/GMRemote.cpp:297 #: src/GMWindow.cpp:1197 msgid "&Play" msgstr "Re&produzir" #: src/GMRemote.cpp:298 msgid "&Stop" msgstr "P&arar" #: src/GMRemote.cpp:300 msgid "Show Browser" msgstr "Mostrar explorador" #: src/GMRemote.cpp:301 #: src/GMTrayIcon.cpp:307 msgid "Quit" msgstr "Sair" #: src/GMRemote.cpp:385 msgid "\tShow Browser\tShow Browser" msgstr "\tMostrar explorador\tMostrar explorador" #: src/GMRemote.cpp:387 msgid "\tStart Playback\tStart Playback" msgstr "\tIniciar reprodução\tIniciar reprodução" #: src/GMRemote.cpp:388 msgid "\tStop Playback\tStop Playback" msgstr "\tParar reprodução\tParar reprodução" #: src/GMRemote.cpp:390 msgid "\tPlay Previous Track\tPlay previous track." msgstr "\tReproduzir faixa anterior\tReproduzir faixa anterior" #: src/GMRemote.cpp:391 msgid "\tPlay Next Track\tPlay next track." msgstr "\tReproduzir faixa seguinte\tReproduzir faixa seguinte" #: src/GMRemote.cpp:397 #: src/GMWindow.cpp:222 msgid "\tAdjust Volume\tAdjust Volume" msgstr "\tAjustar volume\tAjustar volume" #: src/GMSearch.cpp:128 msgid "Unable to open the database" msgstr "Incapaz de abrir a base de dados" #: src/GMSearch.cpp:252 msgid "Database Error: Unable to retrieve all filenames." msgstr "Erro na base de dados: incapaz de obter nome dos ficheiros" #: src/GMSearch.cpp:280 msgid "Unable to update track" msgstr "Incapaz de atualizar faixa" #: src/GMSearch.cpp:439 msgid "Unable to insert track into the database" msgstr "Incapaz de inserir a faixa na base de dados" #: src/GMSearch.cpp:505 #: src/GMTrackDatabase.cpp:205 msgid "Fatal Error" msgstr "Erro fatal" #: src/GMSearch.cpp:505 #, c-format msgid "" "%s\n" "Please contact support if this error keeps occuring." msgstr "" "%s\n" "Contacte o programador se este erro voltar a ocorrer" #: src/GMSearch.cpp:534 #: src/GMSearch.cpp:584 msgid "Updating Database..." msgstr "A atualizar base de dados..." #: src/GMSearch.cpp:537 #: src/GMSearch.cpp:626 msgid "Please wait. This may take a while." msgstr "Por favor, aguarde. Pode levar algum tempo." #: src/GMSearch.cpp:555 #: src/GMSearch.cpp:637 msgid "New Tracks:" msgstr "Novas faixas:" #: src/GMSearch.cpp:561 #: src/GMSearch.cpp:643 msgid "File:" msgstr "Ficheiro:" #: src/GMSearch.cpp:594 #: src/GMSearch.cpp:623 msgid "Importing Files..." msgstr "A importar ficheiros..." #: src/GMSearch.cpp:652 msgid "&Stop Import" msgstr "&Parar importação" #: src/GMSourceView.cpp:54 msgid "Sources\tPress to change sorting order\tPress to change sorting order" msgstr "Fontes\tPrima para alterar a ordem\tPrima para alterar a ordem" #: src/GMSourceView.cpp:245 #: src/GMWindow.cpp:261 msgid "New Playlist…\t\tCreate a new playlist" msgstr "Nova lista de reprodução…\t\tCriar lista de reprodução" #: src/GMSourceView.cpp:246 #: src/GMWindow.cpp:262 msgid "Import Playlist…\t\tImport existing playlist" msgstr "Importar lista de reprodução…\t\tImportar lista de reprodução" #: src/GMSourceView.cpp:247 #: src/GMWindow.cpp:263 msgid "New Radio Station…\t\tCreate a new playlist" msgstr "Nova estação de rádio…\t\tCriar lista de reprodução" #: src/GMStreamSource.cpp:64 msgid "Station" msgstr "Estação" #: src/GMStreamSource.cpp:112 #: src/GMStreamSource.cpp:118 msgid "New Station…\t\t" msgstr "Nova estação…\t\t" #: src/GMStreamSource.cpp:117 msgid "Edit…\t\t" msgstr "Editar…\t\t" #: src/GMStreamSource.cpp:119 msgid "Remove\t\tRemove." msgstr "Remover\t\tRemover" #: src/GMStreamSource.cpp:165 #: src/GMStreamSource.cpp:166 msgid "New Internet Radio Station" msgstr "Nova estação de rádio" #: src/GMStreamSource.cpp:166 msgid "Specify url and description of new station" msgstr "Indique o URL e a descrição da estação" #: src/GMStreamSource.cpp:168 msgid "C&reate" msgstr "C&riar" #: src/GMStreamSource.cpp:173 #: src/GMStreamSource.cpp:211 msgid "Location" msgstr "Endereço" #: src/GMStreamSource.cpp:175 #: src/GMStreamSource.cpp:214 msgid "Description" msgstr "Descrição" #: src/GMStreamSource.cpp:189 msgid "Untitled" msgstr "Sem nome" #: src/GMStreamSource.cpp:202 #: src/GMStreamSource.cpp:203 msgid "Edit Internet Radio Station" msgstr "Editar estação de rádio" #: src/GMStreamSource.cpp:203 msgid "Update url and description of station" msgstr "Atualizar URL e descrição da estação" #: src/GMStreamSource.cpp:265 msgid "Remove Internet Radio Station(s)?" msgstr "Remover estações de rádio?" #: src/GMStreamSource.cpp:266 msgid "Remove Internet Radio Station(s) from library?" msgstr "Remover da coleção as estações de rádio?" #: src/GMStreamSource.cpp:280 #, c-format msgid "Unable to remove station from the library." msgstr "Incapaz de remover a estação da coleção" #: src/GMTrackDatabase.cpp:193 msgid "" "An incompatible (future) version of the database was found.\n" "This usually happens when you try to downgrade to a older version of GMM\n" "Press OK to continue and reset the database (all information will be lost!).\n" "Press Cancel to quit now and leave the database as is." msgstr "" "Foi encontrada uma base de dados incompatível.\n" "Normalmente, esta situação ocorre ao instalar uma versão antiga do GMM\n" "Prima OK para continuar e iniciar a base de dados (as informações serão perdidas!).\n" "Prima Cancelar para sair e manter a base de dados intacta." #: src/GMTrackDatabase.cpp:205 msgid "" "Goggles Music Manager was unable to open the database.\n" "The database may have been corrupted. Please remove ~/.goggles/goggles.db to try again.\n" "if the error keeps occuring, please file an issue at http://code.google.com/p/gogglesmm" msgstr "" "O Goggles Music Manager não conseguiu abrir a base de dados.\n" "É possível que a base de dados esteja danificada. Remova o ficheiro ~/.goggles/goggles.db e tente novamente.\n" "Se este erro voltar a ocorrer, reporte-o em http://code.google.com/p/gogglesmm" #: src/GMTrackView.cpp:245 msgid "\tClose Filter\tClose Filter" msgstr "\tFechar filtro\tFechar filtro" #: src/GMTrackView.cpp:246 msgid "&Find" msgstr "&Procurar" #: src/GMTrackView.cpp:252 msgid "Tags\tPress to change sorting order\tPress to change sorting order" msgstr "Detalhes\tPrima para alterar a ordem\tPrima para alterar a ordem" #: src/GMTrackView.cpp:256 msgid "Artists\tPress to change sorting order\tPress to change sorting order" msgstr "Artistas\tPrima para alterar a ordem\tPrima para alterar a ordem" #: src/GMTrackView.cpp:260 msgid "Albums\tPress to change sorting order\tPress to change sorting order" msgstr "Álbuns\tPrima para alterar a ordem\tPrima para alterar a ordem" #: src/GMTrackView.cpp:282 #: src/GMWindow.cpp:299 msgid "&Configure Columns…" msgstr "&Configurar colunas..." #: src/GMTrackView.cpp:286 msgid "Browse" msgstr "Explorar" #: src/GMTrackView.cpp:287 msgid "Shuffle\tCtrl-R" msgstr "Baralhar\tCtrl-R" #: src/GMTrackView.cpp:294 #: ../../../fox-1.6.37/src/FXDirSelector.cpp:388 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:734 msgid "Reverse" msgstr "Inverter" #: src/GMTrackView.cpp:804 #, c-format msgid "All %d Genres" msgstr "Todos os %d géneros" #: src/GMTrackView.cpp:806 msgid "All Genres" msgstr "Todos os géneros" #: src/GMTrackView.cpp:832 #, c-format msgid "All %d Artists" msgstr "Todos os %d artistas" #: src/GMTrackView.cpp:872 #, c-format msgid "All %d Albums" msgstr "Todos os %d álbuns" #: src/GMTrackView.cpp:1258 #, c-format msgid "By %s" msgstr "Por %s" #: src/GMTrackView.cpp:1586 #: src/GMTrackView.cpp:1609 msgid "Sort by Album Year" msgstr "Ordenar por ano" #: src/GMTrackView.cpp:1637 msgid "&Columns\t\tChange Visible Columns." msgstr "&Colunas\t\tAlterar colunas visíveis" #: src/GMTrackView.cpp:1638 msgid "&Sort\t\tChange Sorting." msgstr "Or&denar\t\tAlterar ordem" #: src/GMTrayIcon.cpp:302 #: src/GMWindow.cpp:841 #: src/GMWindow.cpp:925 #: src/GMWindow.cpp:948 #: src/GMWindow.cpp:954 msgid "Play" msgstr "Reproduzir" #: src/GMTrayIcon.cpp:303 #: src/GMWindow.cpp:843 msgid "Stop" msgstr "Parar" #: src/GMTrayIcon.cpp:304 msgid "Previous Track" msgstr "Faixa anterior" #: src/GMTrayIcon.cpp:305 msgid "Next Track" msgstr "Faixa seguinte" #: src/GMWindow.cpp:205 msgid "Play\tStart Playback\tStart Playback" msgstr "Reproduzir\tIniciar reprodução\tIniciar reprodução" #: src/GMWindow.cpp:205 msgid "Pause\tPause\tPause Playback" msgstr "Pausa\tPausa\tPausar reprodução" #: src/GMWindow.cpp:206 msgid "Stop\tStop Playback\tStop Playback" msgstr "Parar\tParar reprodução\tParar reprodução" #: src/GMWindow.cpp:208 msgid "Previous\tPlay Previous Track\tPlay previous track." msgstr "Anterior\tReproduzir faixa anterior\tReproduzir faixa anterior" #: src/GMWindow.cpp:209 msgid "Next\tPlay Next Track\tPlay next track." msgstr "Seguinte\tReproduzir faixa seguinte\tReproduzir faixa seguinte" #: src/GMWindow.cpp:255 msgid "&Music" msgstr "&Música" #: src/GMWindow.cpp:256 msgid "Import Folder…\tCtrl-O\tImport Music from folder into Library" msgstr "Importar pasta…\tCtrl-O\tImportar músicas de uma pasta para a coleção" #: src/GMWindow.cpp:257 msgid "Sync Folder…\t\tSynchronize Folder with Music in Library" msgstr "Sincronizar pasta…\t\tSincronizar pasta com as músicas da coleção" #: src/GMWindow.cpp:259 msgid "Play File or Stream…\t\tPlay File or Stream" msgstr "Reproduzir ficheiro ou emissão…\t\tReproduzir ficheiro ou emissão" #: src/GMWindow.cpp:266 msgid "&Quit\tCtrl-Q\tQuit the application." msgstr "&Sair\tCtrl-Q\tSair da aplicação" #: src/GMWindow.cpp:271 msgid "&Edit" msgstr "&Editar" #: src/GMWindow.cpp:272 msgid "&Copy\tCtrl-C\tCopy Selected Tracks" msgstr "&Copiar\tCtrl-C\tCopiar faixas selecionadas" #: src/GMWindow.cpp:273 msgid "&Cut\tCtrl-X\tCut Selected Tracks" msgstr "Cor&tar\tCtrl-X\tCortar faixas selecionadas" #: src/GMWindow.cpp:274 msgid "&Paste\tCtrl-V\tPaste Clipboard Selection" msgstr "C&olar\tCtrl-V\tColar dados da área de transferência" #: src/GMWindow.cpp:276 msgid "Find…\tCtrl-F\tShow search filter." msgstr "Procurar…\tCtrl-F\tMostrar filtro de procura" #: src/GMWindow.cpp:278 msgid "Preferences…" msgstr "Preferências" #: src/GMWindow.cpp:282 msgid "&View" msgstr "&Ver" #: src/GMWindow.cpp:283 msgid "&Browse\tCtrl-B\tShow genre artist and album browser." msgstr "E&xplorar\tCtrl-B\tMostrar género, artista e ábum" #: src/GMWindow.cpp:284 msgid "Show &Genres\tCtrl-G\tShow genre browser." msgstr "Mostrar &género\tCtrl-G\tMostrar género" #: src/GMWindow.cpp:287 #: src/GMWindow.cpp:289 msgid "Show &Sources\tCtrl-S\tShow source browser " msgstr "Mostrar fonte&s\tCtrl-S\tMostrar fontes" #: src/GMWindow.cpp:294 msgid "Show Full Screen\tF12\tToggle fullscreen mode." msgstr "Mostrar ecrã completo\tF12\tTrocar modo de ecrã completo" #: src/GMWindow.cpp:296 msgid "Show Mini Player\tCtrl-M\tToggle Mini Player." msgstr "Mostrar reprodutor pequeno\tCtrl-M\tTrocar esquema de reprodutor" #: src/GMWindow.cpp:300 msgid "&Sort" msgstr "Or&dem" #: src/GMWindow.cpp:302 msgid "&Jump to Current Track\tCtrl-J\tShow current playing track." msgstr "&Ir para a faixa atual\tCtrl-J\tMostrar a faixa em reprodução" #: src/GMWindow.cpp:306 msgid "&Control" msgstr "&Controlo" #: src/GMWindow.cpp:307 msgid "Play\tCtrl-P\tStart playback." msgstr "Reproduzir\tCtrl-P\tIniciar reprodução" #: src/GMWindow.cpp:308 msgid "Stop\tCtrl-\\\tStop playback." msgstr "Parar\tCtrl-\\\tParar reprodução" #: src/GMWindow.cpp:309 msgid "Previous Track\tCtrl-[\tPlay next track." msgstr "Faixa anterior\tCtrl-[\tReproduzir faixa anterior" #: src/GMWindow.cpp:310 msgid "Next Track\tCtrl-]\tPlay previous track." msgstr "Faixa seguinte\tCtrl-]\tReproduzir faixa seguinte" #: src/GMWindow.cpp:312 msgid "Repeat Off\tCtrl-,\tRepeat current track." msgstr "Não repetir\tCtrl-,\tNão repetir faixa" #: src/GMWindow.cpp:313 msgid "Repeat Track\tCtrl-.\tRepeat current track." msgstr "Repetir faixa\tCtrl-.\tRepetir faixa atual" #: src/GMWindow.cpp:314 msgid "Repeat All Tracks\tCtrl-/\tRepeat all tracks." msgstr "Repetir todas\tCtrl-/\tRepetir todas as faixas" #: src/GMWindow.cpp:315 msgid "Repeat A-B\tCtrl-T\tRepeat section of track." msgstr "Repetir A-B\tCtrl-T\tRepetir secção da faixa" #: src/GMWindow.cpp:316 msgid "Shuffle Mode\tAlt-R\tPlay tracks in random order." msgstr "Baralhar\tAlt-R\tReproduzir faixas aleatoriamente" #: src/GMWindow.cpp:318 msgid "Equalizer\t\t" msgstr "Equalizador\t\t" #: src/GMWindow.cpp:319 msgid "Sleep Timer\t\tSetup sleeptimer." msgstr "Intervalo\t\tConfigurar intervalo" #: src/GMWindow.cpp:323 msgid "&Help" msgstr "Aju&da" #: src/GMWindow.cpp:324 msgid "&Homepage" msgstr "Pa&gina inicial" #: src/GMWindow.cpp:325 msgid "&Report Issue…" msgstr "&Reportar problema..." #: src/GMWindow.cpp:327 msgid "&Sign up for last.fm…" msgstr "Iniciar &sessão na last.fm..." #: src/GMWindow.cpp:328 msgid "&Join GMM on last.fm…\t\tJoin the Goggles Music Manager group on last.fm…" msgstr "Integrar o gr&upo GMM da last.fm...\t\tIntegração no grupo GMM da last.fm..." #: src/GMWindow.cpp:330 msgid "&About…" msgstr "So&bre" #: src/GMWindow.cpp:842 #: src/GMWindow.cpp:940 msgid "Pause" msgstr "Pausa" #: src/GMWindow.cpp:844 msgid "Previous" msgstr "Anterior" #: src/GMWindow.cpp:845 msgid "Next" msgstr "Seguinte" #: src/GMWindow.cpp:920 #: src/GMWindow.cpp:949 #: src/GMWindow.cpp:955 msgid "Start playback." msgstr "Iniciar reprodução" #: src/GMWindow.cpp:926 #: src/GMWindow.cpp:927 msgid "Start playback" msgstr "Iniciar reprodução" #: src/GMWindow.cpp:934 #: src/GMWindow.cpp:941 msgid "Pause playback." msgstr "Pausar reprodução" #: src/GMWindow.cpp:935 msgid "Pause playback" msgstr "Pausar reprodução" #: src/GMWindow.cpp:1052 #: src/GMWindow.cpp:1054 msgid "Repeat A-B" msgstr "Repetir A-B" #: src/GMWindow.cpp:1053 msgid "Repeat A" msgstr "Repetir A" #: src/GMWindow.cpp:1195 msgid "Play File or Stream" msgstr "Reproduzir ficheiro ou emissão" #: src/GMWindow.cpp:1202 msgid "Please specify a file or url to play:" msgstr "Indique o ficheiro ou URL a reproduzir:" #: src/GMWindow.cpp:1206 msgid "…" msgstr "…" #: src/GMWindow.cpp:1212 msgid "Select File" msgstr "Selecione o ficheiro" #: src/GMWindow.cpp:1243 msgid "Sleep Timer" msgstr "Intervalo" #: src/GMWindow.cpp:1244 msgid "Setup sleep timer" msgstr "Configurar intervalo" #: src/GMWindow.cpp:1244 msgid "Stop playback within a certain time" msgstr "Parar reprodução após um intervalo de tempo" #: src/GMWindow.cpp:1246 msgid "&Start Timer" msgstr "&Ativar" #: src/GMWindow.cpp:1251 msgid "Sleep in" msgstr "Parar em" #: src/GMWindow.cpp:1253 msgid "hours and" msgstr "horas e" #: src/GMWindow.cpp:1255 msgid "minutes." msgstr "minutos" #: src/GMDatabaseSource.h:131 msgid "Music Library" msgstr "Coleção" #: src/GMStreamSource.h:57 msgid "Internet Radio" msgstr "Rádio na internet" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:122 #: ../../../fox-1.6.37/src/FXMessageBox.cpp:127 msgid "&Quit" msgstr "&Sair" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:133 msgid "&Skip" msgstr "I&gnorar" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:134 msgid "Skip &All" msgstr "Ignorar tod&as" #: ../../../fox-1.6.37/src/FXMessageBox.cpp:140 msgid "&Don't Save" msgstr "Não &gravar" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:220 msgid "\tPick color" msgstr "\tEscolher cor" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:229 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:274 msgid "\tHue, Saturation, Value" msgstr "\tTom, saturação, valor" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:239 msgid "\tRed, Green, Blue" msgstr "\tVermelho, verde, azul" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:245 msgid "&Red:" msgstr "Ve&rmelho:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:250 msgid "&Green:" msgstr "&Verde:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:255 msgid "&Blue:" msgstr "A&zul:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:260 msgid "&Alpha:" msgstr "&Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:280 msgid "Hue:" msgstr "Tom:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:285 msgid "Saturation:" msgstr "Saturação:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:290 msgid "Value:" msgstr "Valor:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:295 #: ../../../fox-1.6.37/src/FXColorSelector.cpp:330 msgid "Alpha:" msgstr "Alfa:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:309 msgid "\tCyan, Magenta, Yellow" msgstr "\tCiano, magenta, amarelo" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:315 msgid "Cyan:" msgstr "Ciano:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:320 msgid "Magenta:" msgstr "Magenta:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:325 msgid "Yellow:" msgstr "Amarelo:" #: ../../../fox-1.6.37/src/FXColorSelector.cpp:344 msgid "\tBy Name" msgstr "\tPor nome" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:281 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create New Directory" msgstr "Criar novo diretório" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:284 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 msgid "Already Exists" msgstr "Já existe" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:288 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 msgid "Cannot Create" msgstr "Incapaz de criar" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:309 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:595 msgid "Copy File" msgstr "Copiar ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:315 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 msgid "Error Copying File" msgstr "Erro ao copiar ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:326 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:618 msgid "Move File" msgstr "Mover ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:332 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 msgid "Error Moving File" msgstr "Erro ao mover ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:343 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:641 msgid "Link File" msgstr "Ligar ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:349 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 msgid "Error Linking File" msgstr "Erro ao ligar ao ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:359 msgid "Deleting file" msgstr "A eliminar ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:361 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 msgid "Error Deleting File" msgstr "Erro ao eliminar ficheiro" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:381 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:719 msgid "Up one level" msgstr "Subir um nível" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:382 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:720 msgid "Home directory" msgstr "Diretório pessoal" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:383 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:721 msgid "Work directory" msgstr "Diretório de trabalho" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:387 msgid "Sorting" msgstr "Ordenação" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:389 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:735 msgid "Ignore case" msgstr "Ignorar capitulares" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:390 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:746 msgid "Hidden files" msgstr "Ficheiros ocultos" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:393 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:754 msgid "Bookmarks" msgstr "Marcadores" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:394 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:757 msgid "Set bookmark" msgstr "Definir marcador" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:395 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:758 msgid "Clear bookmarks" msgstr "Apagar marcadores" #: ../../../fox-1.6.37/src/FXDirSelector.cpp:411 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:774 msgid "New directory..." msgstr "Novo diretório..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:412 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:775 msgid "Copy..." msgstr "Copiar..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:413 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:776 msgid "Move..." msgstr "Mover..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:414 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:777 msgid "Link..." msgstr "Ligação..." #: ../../../fox-1.6.37/src/FXDirSelector.cpp:415 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:778 msgid "Delete..." msgstr "Eliminar..." #: ../../../fox-1.6.37/src/FXFileList.cpp:195 msgid "Modified Date" msgstr "Data de modificação" #: ../../../fox-1.6.37/src/FXFileList.cpp:196 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:731 msgid "User" msgstr "Utilizador" #: ../../../fox-1.6.37/src/FXFileList.cpp:197 #: ../../../fox-1.6.37/src/FXFileSelector.cpp:732 msgid "Group" msgstr "Grupo" #: ../../../fox-1.6.37/src/FXFileList.cpp:198 msgid "Attributes" msgstr "Atributos" #: ../../../fox-1.6.37/src/FXFileList.cpp:200 msgid "Link" msgstr "Ligação" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:521 msgid "Create new directory with name: " msgstr "Criar novo diretório com o nome:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:524 #, c-format msgid "File or directory %s already exists.\n" msgstr "O ficheiro ou diretório %s já existe.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:528 #, c-format msgid "Cannot create directory %s.\n" msgstr "Incapaz de criar o diretório %s.\n" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:594 #, c-format msgid "" "Copy file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Copiar ficheiro de:\n" "\n" "%s\n" "\n" "para: " #: ../../../fox-1.6.37/src/FXFileSelector.cpp:601 #, c-format msgid "" "Unable to copy file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Incapaz de copiar:\n" "\n" "%s para: %s\n" "\n" "Continuar?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:617 #, c-format msgid "" "Move file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Mover ficheiro de:\n" "\n" "%s\n" "\n" "para:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:624 #, c-format msgid "" "Unable to move file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Incapaz de mover:\n" "\n" "%s para: %s\n" "\n" "Continuar?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:640 #, c-format msgid "" "Link file from location:\n" "\n" "%s\n" "\n" "to location: " msgstr "" "Cria ligação de:\n" "\n" "%s\n" "\n" "para:" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:647 #, c-format msgid "" "Unable to link file:\n" "\n" "%s to: %s\n" "\n" "Continue with operation?" msgstr "" "Incapaz de criar ligação de:\n" "\n" "%s para: %s\n" "\n" "Continuar?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 msgid "Deleting files" msgstr "A eliminar ficheiros" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:663 #, c-format msgid "" "Are you sure you want to delete the file:\n" "\n" "%s" msgstr "" "Tem a certeza de que pretende eliminar:\n" "\n" "%s ?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:667 #, c-format msgid "" "Unable to delete file:\n" "\n" "%s\n" "\n" "Continue with operation?" msgstr "" "Incapaz de eliminar:\n" "\n" "%s\n" "\n" "Continuar?" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:722 msgid "Select all" msgstr "Selecionar tudo" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:726 msgid "Sort by" msgstr "Ordenar por" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:738 msgid "View" msgstr "Ver" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:739 msgid "Small icons" msgstr "Ícones pequenos" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:740 msgid "Big icons" msgstr "Ícones grandes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:741 msgid "Details" msgstr "Detalhes" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:743 msgid "Rows" msgstr "Linhas" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:744 msgid "Columns" msgstr "Colunas" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:747 msgid "Preview images" msgstr "Ver imagens" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:749 msgid "Normal images" msgstr "Normais" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:750 msgid "Medium images" msgstr "Médias" #: ../../../fox-1.6.37/src/FXFileSelector.cpp:751 msgid "Giant images" msgstr "Grandes" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:111 msgid "&Replace" msgstr "Substitui&r" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:112 msgid "Re&place All" msgstr "Subs&tituir tudo" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:121 msgid "S&earch for:" msgstr "P&esquisar:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:129 msgid "Replace &with:" msgstr "Su&bstituir por:" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:138 msgid "Ex&act" msgstr "Ex&ata" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:139 msgid "&Ignore Case" msgstr "&Ignorar capitulares" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:140 msgid "E&xpression" msgstr "E&xpressão" #: ../../../fox-1.6.37/src/FXReplaceDialog.cpp:141 msgid "&Backward" msgstr "&Voltar" #: ../../../fox-1.6.37/src/FXSearchDialog.cpp:71 msgid "&Search" msgstr "Pe&squisar" #: ../../../fox-1.6.37/src/FXStatusLine.cpp:82 msgid "Ready." msgstr "Pronto" #~ msgid "New Name" #~ msgstr "Novo nome" gogglesmm-0.12.7/configure0000755000175000001440000002172711701202271014216 0ustar sxjusers#!/bin/sh #----------------------------- . build/version . build/functions # Settings #--------------------------- DEBUG=0 DBUS=1 FOX17=0 HELP=0 NLS=1 MD5=gcrypt PREFIX=${PREFIX:-/usr} # Default Compiler Settings # Use environment variables to override #-------------------------- CXX=${CXX:-g++} LINK=${LINK:-g++} INCFLAGS=${INCFLAGS:-} LIBS=${LIBS:-} LIBPREFIX=${LIBPREFIX:-lib} LIBEXT=${LIBEXT:-.so} OUTPUTOBJ=${OUTPUTOBJ:--o } OUTPUTBIN=${OUTPUTBIN:--o } OBJEXT=${OBJEXT:-.o} # Overriding Compiler Flags # Either override GEN_CFLAGS, OPT_CFLAGS and DEBUG_CFLAGS individually # or set CFLAGS which overrides all them #------------------------------------------------------- GEN_CFLAGS=${GEN_CFLAGS:--Wall -Wextra -Wformat=2 -pipe} OPT_CFLAGS=${OPT_CFLAGS:--O3 -march=native -fstack-protector} DEBUG_CFLAGS=${DEBUG_CFLAGS:--g -fstack-protector-all} # Overriding Linker Flags # Either override GEN_LDFLAGS, OPT_LDFLAGS and DEBUG_LDFLAGS individually # or set LDFLAGS which overrides all them #------------------------------------------------------- GEN_LDFLAGS=${GEN_LDFLAGS:-} OPT_LDFLAGS=${OPT_LDFLAGS:--s} DEBUG_LDFLAGS=${DEBUG_LDFLAGS:-} # Parse Command Line Arguments #----------------------------- for arg in $@; do case $arg in --enable-debug) DEBUG=1 ;; --with-md5=*) MD5=${arg#*=} ;; --disable-nls) NLS=0 ;; --without-dbus) DBUS=0 ;; --prefix=*) PREFIX=${arg#*=} ;; --fox-prefix=*) FOX_PREFIX=${arg#*=} add_package_path $FOX_PREFIX ;; --xine-prefix=*) XINE_PREFIX=${arg#*=} add_package_path $XINE_PREFIX ;; --sqlite-prefix=*) SQLITE_PREFIX=${arg#*=} add_package_path $SQLITE_PREFIX ;; --taglib-prefix=*) TAGLIB_PREFIX=${arg#*=} add_package_path $TAGLIB_PREFIX ;; --dbus-prefix=*) DBUS_PREFIX=${arg#*=} add_package_path $DBUS_PREFIX ;; --localedir=*) NLSDIR=${arg#*=} ;; --mandir=*) MANDIR=${arg#*=} ;; --with-fox17) FOX17=1 ;; --help) HELP=1 ;; -h) HELP=1 ;; esac done # Print Command Line Options #--------------------------- if [ $HELP -eq 1 ] ; then echo "Available options:" echo " --enable-debug Compile with debug information" echo " --with-md5=gcrypt,internal Select which md5 implementation to use. (gcrypt)" echo " --without-dbus Turn off DBus Support" echo " --without-new-remote Disable new remote and use old mini player." echo " --with-fox17 Compile with FOX 1.7.x." echo " --prefix=

Installation prefix (/usr)" echo " --fox-prefix=

fox prefix path" echo " --xine-prefix=

xinelib prefix path" echo " --taglib-prefix=

tagLib prefix path" echo " --sqlite-prefix=

sqlite prefix path" echo " --dbus-prefix=

dbus prefix path" echo " --localedir=

locale-dependent data (/share/locale)" echo " --mandir= man pages (/share/man)" echo " -h,--help Show Help" exit 0 fi # Debug / Release Mode #---------------------- if [ $DEBUG -eq 1 ] ; then CFLAGS=${CFLAGS:-$GEN_CFLAGS $DEBUG_CFLAGS} LDFLAGS=${LDFLAGS:-$GEN_LDFLAGS $DEBUG_LDFLAGS} DEFINES="$DEFINES -DDEBUG" else CFLAGS=${CFLAGS:-$GEN_CFLAGS $OPT_CFLAGS} LDFLAGS=${LDFLAGS:-$GEN_LDFLAGS $OPT_LDFLAGS} DEFINES="$DEFINES -DNDEBUG" fi # Init Config File #------------------------------ echo "/* Generated by configure utility */" > $CFG echo "#ifndef GMCONFIG_H" >> $CFG echo "#define GMCONFIG_H" >> $CFG echo "" >> $CFG echo "#define APPLICATION_MAJOR $MAJOR" >> $CFG echo "#define APPLICATION_MINOR $MINOR" >> $CFG echo "#define APPLICATION_LEVEL $LEVEL" >> $CFG echo "#define APPLICATION_BETA $BETA_APP" >> $CFG echo "#define APPLICATION_BETA_DB $BETA_DB" >> $CFG echo "#define BUILD_DATE __DATE__" >> $CFG echo "#define BUILD_TIME __TIME__" >> $CFG echo "" >> $CFG if [ $BETA_APP -eq 0 ] ; then echo "#define APPLICATION_VERSION_STRING \"$MAJOR.$MINOR.$LEVEL\"" >> $CFG else echo "#define APPLICATION_VERSION_STRING \"$MAJOR.$MINOR.$LEVEL-rc$BETA_APP\"" >> $CFG fi echo "" >> $CFG echo "" echo "Goggles Music Manager:" # Libraries #------------------------ if [ $FOX17 -eq 1 ] ; then add_required_package "fox17 >= 1.7" "fox" else add_required_package "fox >= 1.6" "fox" fi check_reswrap check_foxversion add_required_package "sqlite3 >= 3.6.3" "sqlite" add_required_package "taglib >= ${TAGLIB_VERSION:-1.6.3}" "taglib" # DBus is optional if [ $DBUS -eq 1 ] ; then add_package "dbus-1 >= 1.0" "dbus" DBUS=$? fi # We need both X11 and GLU # For systems without pkg-config for x11 and glu we'll just hardwire it. add_package "x11" "x11" if [ $? -eq 0 ] ; then EXTRALIBS="$EXTRALIBS -lX11" fi add_package "glu" "glu" if [ $? -eq 0 ] ; then EXTRALIBS="$EXTRALIBS -lGL -lGLU" fi # xine >= 1.2.0 use pkg-config add_package "libxine" "libxine" if [ $? -eq 0 ] ; then # Old xine is still supported... XINE_MAJOR=${XINE_MAJOR:-1} XINE_MINOR=${XINE_MINOR:-1} XINE_LEVEL=${XINE_LEVEL:-16} if [ -n "$XINE_PREFIX" ] ; then check_in_prefix "XINE" $XINE_PREFIX "xine-config" $XINE_MAJOR $XINE_MINOR $XINE_LEVEL if [ $? -eq 0 ] ; then echo " Unable to find a compatible XINE library installation. Please make" echo " sure the correct version is installed including the header files." echo " You can use the \"--xine-prefix\" option to search in an" echo " alternative installation directory." exit -1 fi else check_in_prefix "XINE" "/usr" "xine-config" $XINE_MAJOR $XINE_MINOR $XINE_LEVEL if [ $? -eq 0 ] ; then check_in_prefix "XINE" "/usr/local" "xine-config" $XINE_MAJOR $XINE_MINOR $XINE_LEVEL if [ $? -eq 0 ] ; then echo " Unable to find a compatible XINE library installation. Please make" echo " sure the correct version is installed including the header files." echo " You can use the \"--xine-prefix\" option to search in an" echo " alternative installation directory." exit -1 fi fi fi add_config "libxine" fi PKG_LDFLAGS=$(pkg-config --libs-only-L $PACKAGES) PKG_LIBS=$(pkg-config --libs-only-l --libs-only-other $PACKAGES) PKG_CFLAGS=$(pkg-config --cflags-only-other $PACKAGES) PKG_CPPFLAGS=$(pkg-config --cflags-only-I $PACKAGES) if [ -n "$PKG_LDFLAGS" ] ; then LIBS="$LIBS $PKG_LDFLAGS"; fi if [ -n "$PKG_LIBS" ] ; then LIBS="$LIBS $PKG_LIBS"; fi if [ -n "$PKG_CFLAGS" ] ; then GEN_CFLAGS="$GEN_CFLAGS $PKG_CFLAGS"; fi if [ -n "$PKG_CPPFLAGS" ] ; then INCFLAGS="$INCFLAGS $PKG_CPPFLAGS"; fi . build/byteorderdetect if [ $NLS -eq 1 ] ; then NLSDIR=${NLSDIR:-$PREFIX/share/locale} add_config "nls" add_config_string "LOCALEDIR" ${NLSDIR} fi if [ "$MD5" != "internal" ] ; then add_config "gcrypt" GCRYPT_LIBS=$(libgcrypt-config --libs) LIBS="$LIBS $GCRYPT_LIBS" else add_config "md5" fi #Set MANDIR MANDIR=${MANDIR:-$PREFIX/share/man} # expat (for now hardwired) #------------------------ LIBS="$LIBS $EXTRALIBS -lexpat" # End of configuration #------------------------- echo "" >> $CFG echo "#endif" >> $CFG # Write out Makefile configuration #-------------------------------------- echo "#Generated by configure utility" > config.make echo "CXX=$CXX" >> config.make echo "LINK=$LINK" >> config.make echo "CFLAGS=$CFLAGS" >> config.make echo "CPPFLAGS=$DEFINES $INCFLAGS" >> config.make echo "LDFLAGS=$LDFLAGS" >> config.make echo "LIBS=$LIBS" >> config.make echo "OUTPUTOBJ=$OUTPUTOBJ" >> config.make echo "OUTPUTBIN=$OUTPUTBIN" >> config.make echo "OBJEXT=$OBJEXT" >> config.make echo "RESWRAP_CPP=$RESWRAP_CPP" >> config.make echo "RESWRAP_H=$RESWRAP_H" >> config.make echo "RESWRAP_TEXT=$RESWRAP_TEXT" >> config.make echo "PREFIX=$PREFIX" >> config.make echo "OPTIONS=$OPTIONS" >> config.make echo "LOCALEDIR=$NLSDIR" >> config.make echo "MANDIR=$MANDIR" >> config.make # Summary #------------------------- echo "Features:" if [ "$MD5" != "internal" ] ; then echo " MD5 => libgcrypt" else echo " MD5 => internal" fi if [ $DBUS -eq 0 ] ; then echo " DBUS Support => no" else echo " DBUS Support => yes" fi if [ $NLS -eq 0 ] ; then echo " NLS Support => no" else echo " NLS Support => yes" echo " Locale Path => $NLSDIR" fi echo " Man Path => $MANDIR" echo " Install Path => $PREFIX" # Success #-------------------------------------- echo "" echo "Done." echo "Please run \"make\" and \"make install\" to compile and install GMM." exit 0