/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "swidget/SFileDialog.h" #include "swidget/SIcon.h" #include "swidget/SIconFactory.h" #include "stoolkit/SUtil.h" #include "stoolkit/SEncoder.h" /** * Hidden Filter Type * Directories Files Types * +--------+ +-------+ +---+ * | | | | | | * | | | | | | * | | | | | | * +--------+ +-------+ +---+ * ______directory * ______pathname___________ * OK CD mkdir Cancel */ SFileDialog::SFileDialog (void) { setFrameListener (this); hiddenButton = new SButton (translate ("Show Hidden")); hiddenButton->setButtonListener (this); hiddenButton->setAlignment (SD_Center); hiddenButton->setIcon(SIconFactory::getIcon("CircleOff")); homeButton = new SButton (translate ("Home"), SIconFactory::getIcon("Home")); homeButton->setButtonListener (this); homeButton->setAlignment (SD_Center); add (homeButton); isFocused = false; isCancel = true; showHidden = false; setHidden (); add (hiddenButton); yesButton = new SButton (translate ("OK"), SIconFactory::getIcon("Yes")); yesButton->setAlignment (SD_Center); yesButton->setButtonListener (this); cdButton = new SButton (translate ("CD to"), SIconFactory::getIcon("Folder")); cdButton->setAlignment (SD_Center); cdButton->setButtonListener (this); createButton = new SButton (translate ("Make Folder"), SIconFactory::getIcon("CreateFolder")); createButton->setAlignment (SD_Center); createButton->setButtonListener (this); cancelButton = new SButton (translate ("Cancel"), SIconFactory::getIcon("Cancel")); cancelButton->setAlignment (SD_Center); cancelButton->setButtonListener (this); add (yesButton); add (cdButton); add (createButton); add (cancelButton); folderListBox = new SListBox(translate ("Folder")); folderListBox->setListListener (this); add (folderListBox); fileListBox = new SListBox(translate ("File")); fileListBox->setListListener (this); add (fileListBox); fileTypeListBox = new SListBox(translate ("File Type")); fileTypeListBox->setListListener (this); add (fileTypeListBox); fileTitleLabel = new SLabel (translate ("File:")); add (fileTitleLabel); fileTextEdit = new STextEdit(""); fileTextEdit->setMultiline(false); fileTextEdit->setLineEndMark(false); fileTextEdit->addTextEditLS(this); add (fileTextEdit); folderTitleLabel = new SLabel (translate ("Folder:")); add (folderTitleLabel); folderNameLabel = new SLabel (""); add (folderNameLabel); filterTitleLabel = new SLabel (translate ("Filter:")); add (filterTitleLabel); fileFilter = "*"; filterTextEdit = new STextEdit(fileFilter); filterTextEdit->addTextEditLS(this); add (filterTextEdit); filterTextEdit->setMultiline(false); filterTextEdit->setLineEndMark(false); fileTypeButton = new SButton ( translate ("Best File Type"), SIconFactory::getIcon("Best")); fileTypeButton->setButtonListener (this); add (fileTypeButton); fileTypeLabel = new SLabel ("[]"); add (fileTypeLabel); textDialog = new STextDialog(); textDialog->setModal (this); recalc(); } bool SFileDialog::setFileType (const SString& _fileType) { /* add this filetype */ bool exists = true; if (!fileTypeListBox->selectText (_fileType)) { fileTypeVector.append (_fileType); fileTypeVector.sort (); fileTypeListBox->setText(fileTypeVector); exists = false; } fileTypeListBox->selectText (_fileType); fileTypeChanged (_fileType); return exists; } const SStringVector& SFileDialog::getFileTypes() const { return fileTypeVector; } void SFileDialog::setApplicationImage (const SImage& image) { getComponentWindow()->setApplicationImage (image); textDialog->setApplicationImage (image); } void SFileDialog::fileTypeChanged (const SString& _filetype) { //SString a="["; SString a; a.append(_filetype); //a.append("]"); fileTypeLabel->setText (a); fileTypeText = _filetype; } void SFileDialog::rereadDir() { filterChanged (); /* get directories and files */ while (!currentDirectory.exists() || !currentDirectory.readable()) { currentDirectory.cd (".."); if (currentDirectory.getUnixName() == "/") break; } SStringVector files = currentDirectory.list("*"); SStringVector combedFiles; unsigned int i; if (showHidden) { combedFiles = files; } else { for (i=0; isetText(combedFiles); SStringVector dirs = currentDirectory.list(SDir::SE_DIR); SStringVector combedDirs; if (showHidden) { combedDirs = dirs; } else { for (i=0; isetText(combedDirs); folderNameLabel->setText (currentDirectory.getUnixName ()); } void SFileDialog::setFileTypes(const SStringVector& v) { fileTypeVector = v; fileTypeVector.sort(); fileTypeListBox->setText(fileTypeVector); } SFileDialog::~SFileDialog () { } /** * recalcualte the geometry * it is based upon 300x200 layout. * preferredSize will be calculated here. */ void SFileDialog::recalc () { unsigned int bw = 1; if (yesButton->getPreferredSize().width > bw ) { bw = yesButton->getPreferredSize().width; } if (cdButton->getPreferredSize().width > bw ) { bw = cdButton->getPreferredSize().width; } if (createButton->getPreferredSize().width > bw ) { bw = createButton->getPreferredSize().width; } if (cancelButton->getPreferredSize().width > bw ) { bw = cancelButton->getPreferredSize().width; } unsigned int bh= cancelButton->getPreferredSize().height; int gap = (300-((int)bw * 4 + 10))/3; int currentx= 5; yesButton->setLayout ( SLayout ( SLocation (currentx, 195-bh), SLocation (currentx+(int)bw, 195), SLocation (0, 100), SLocation (0, 100) ) ); currentx = currentx + (int) bw + gap; cdButton->setLayout ( SLayout ( SLocation (currentx, 195-bh), SLocation (currentx+(int)bw, 195), SLocation (33, 100), SLocation (33, 100) ) ); currentx = currentx + (int) bw + gap; createButton->setLayout ( SLayout ( SLocation (currentx, 195-bh), SLocation (currentx+(int)bw, 195), SLocation (66, 100), SLocation (66, 100) ) ); currentx = currentx + (int) bw + gap; cancelButton->setLayout ( SLayout ( SLocation (currentx, 195-bh), SLocation (currentx+(int)bw, 195), SLocation (100, 100), SLocation (100, 100) ) ); SDimension hms = homeButton->getPreferredSize(); homeButton->setLayout ( SLayout ( SLocation (5, 5), SLocation ((int)hms.width+5, (int)hms.height+5), SLocation (0, 0), SLocation (0, 0) ) ); SDimension hs = hiddenButton->getPreferredSize(); hiddenButton->setLayout ( SLayout ( SLocation ((int)hms.width+10, 5), SLocation ((int)hms.width + hs.width+10, (int)hs.height+5), SLocation (0, 0), SLocation (0, 0) ) ); SDimension bs = fileTypeButton->getPreferredSize(); fileTypeButton->setLayout ( SLayout ( SLocation (295-(int)bs.width, 5), SLocation (295, (int)bs.height+5), SLocation (100, 0), SLocation (100, 0) ) ); SDimension fs = filterTitleLabel->getPreferredSize(); filterTitleLabel->setLayout ( SLayout ( SLocation ((int)hs.width+(int)hms.width+12, 5), SLocation ((int) fs.width + (int)hs.width+(int)hms.width+12, (int) fs.height+5), SLocation (0, 0), SLocation (0, 0) ) ); filterTextEdit->setLayout ( SLayout ( SLocation ((int) fs.width + (int)hs.width+(int)hms.width+12, 5), SLocation ((int) fs.width + 80 + (int)hs.width+(int)hms.width+12, (int) fs.height+5), SLocation (0, 0), SLocation (0, 0) ) ); /* this will be the text field height */ unsigned int tfh = fileTextEdit->getPreferredSize().height; unsigned int phw = fileTitleLabel->getPreferredSize().width; unsigned int dph = folderTitleLabel->getPreferredSize().height; unsigned int dpw = folderTitleLabel->getPreferredSize().width; folderTitleLabel->setLayout ( SLayout ( SLocation (5, 200-(int)bh-(int)tfh -(int) dph - 10), SLocation (5 + dpw, 200-(int)bh -(int)tfh - 10), SLocation (0, 100), SLocation (0, 100) ) ); folderNameLabel->setLayout ( SLayout ( SLocation (5+dpw, 200-(int)bh-(int)tfh -(int) dph - 10), SLocation (295, 200-(int)bh -(int)tfh - 10), SLocation (0, 100), SLocation (100, 100) ) ); fileTitleLabel->setLayout ( SLayout ( SLocation (5, 200-(int)bh-(int)tfh - 10), SLocation (5 + phw, 200-(int)bh - 10), SLocation (0, 100), SLocation (0, 100) ) ); fileTextEdit->setLayout ( SLayout ( SLocation (5+phw, 200-(int)bh-(int)tfh - 10), SLocation (180, 200-(int)bh - 10), SLocation (0, 100), SLocation (100, 100) ) ); fileTypeLabel->setLayout ( SLayout ( SLocation (180, 200-(int)bh-(int)tfh - 10), SLocation (295, 200-(int)bh - 10), SLocation (100, 100), SLocation (100, 100) ) ); unsigned int incr = (300-10)/3; folderListBox->setLayout ( SLayout ( SLocation (5, (int)hs.height+5+5), SLocation (5+incr-2, 200-(int)bh-(int)tfh -(int) dph - 10), SLocation (0, 0), SLocation (33, 100) ) ); fileListBox->setLayout ( SLayout ( SLocation (5+incr+1, (int)hs.height+5+5), SLocation (300-5-incr-1, 200-(int)bh-(int)tfh-(int) dph - 10), SLocation (33, 0), SLocation (66, 100) ) ); fileTypeListBox->setLayout ( SLayout ( SLocation (300-5-incr+2, (int)hs.height+5+5), SLocation (300-5, 200-(int)bh-(int)tfh-(int) dph - 10), SLocation (66, 0), SLocation (100, 100) ) ); unsigned int bestWidthBottom = bw * 4 + 10 + 15 + 20; /* top */ unsigned int bestWidthTop = 5 + hms.width + 5 + hs.width + 5 +fs.width + 80 + bs.width + 5 + 10; unsigned int bestWidth = (bestWidthTop>bestWidthBottom) ? bestWidthTop : bestWidthBottom; preferredSize = SDimension (bestWidth+10, 300); /* This was out layout... */ forceLayout (SLayout (SDimension (300,200))); /* But this one is the one that works */ setLayout (SLayout (preferredSize)); setMinimumSize (preferredSize); resize (preferredSize); } SString SFileDialog::getFileName () { SString fn = fileTextEdit->getText(); if (fn.size()==0) return SString(fn); SString filePath = currentDirectory.getName(); if (filePath != "/") filePath.append ("/"); filePath.append (fn); return SString(filePath); } SString SFileDialog::getUnixFileName () { SString fn = fileTextEdit->getText(); if (fn.size()==0) return SString(fn); SString filePath = currentDirectory.getUnixName(); if (filePath != "/") filePath.append ("/"); filePath.append (fn); return SString(filePath); } SString SFileDialog::getFileType () { return fileTypeText; } bool SFileDialog::getInput (const SString& titleString, bool shouldExist, bool warnExist) { setTitle (titleString); fileFilter = "*"; filterTextEdit->setText (fileFilter); rereadDir (); center(); isCancel = true; isFocused = false; show(); wait(); textDialog->hide(); hide(); return !isCancel; } /** * buttons call this */ void SFileDialog::buttonPressed (void* source, const SAccelerator* acc) { if (source == createButton) { SString before = currentDirectory.getName(); SDir d(before); SString s(fileTextEdit->getText()); unsigned int ck = 0; bool hasSlash = false; for (ck=0; ckgetInput ("Error", translate ("Will not create\nspecified folder\n"), STextDialog::SS_ERR); return; } if (hasSlash) { textDialog->getInput ("Error", translate ("Folders can be created\nin current directory only."), STextDialog::SS_ERR); return; } if (d.cd (s)) { textDialog->getInput ("Warning", translate ("Specified folder\nalready exists.\n"), STextDialog::SS_WARN); return; } SString cdr = currentDirectory.getName(); if (cdr != "/") cdr.append ("/"); cdr.append (fileTextEdit->getText()); d = SDir (cdr); if (!d.create()) { textDialog->getInput ("Error", translate ("Can not create\nspecified folder\n"), STextDialog::SS_ERR); return; } currentDirectory = d; rereadDir (); fileTextEdit->setText(""); return; } if (source == cdButton) { SString before = currentDirectory.getName(); SDir d(before); if (!d.cd (fileTextEdit->getText())) { textDialog->getInput ("Error", translate ("Can not go to\nspecified folder.\n"), STextDialog::SS_ERR); return; } currentDirectory = d; rereadDir (); fileTextEdit->setText(""); return; } if (source == cancelButton) { isCancel = true; hide(); return; } if (source == yesButton) { isCancel = false; hide(); return; } if (source == fileTypeButton) { setFileType("utf-8"); return; } if (source == hiddenButton) { showHidden = !showHidden; setHidden(); rereadDir(); return; } if (source == homeButton) { currentDirectory.cd (getHome()); rereadDir(); return; } } /** * STextListListener */ void SFileDialog::itemSelected (void* source, const SAccelerator* acc) { if (source == folderListBox->textList) { SString s = folderListBox->textList->getLastSelectedText(); SString before = currentDirectory.getName(); //fprintf (stderr, "before %*.*s [%*.*s]\n", SSARGS (s), SSARGS(before)); currentDirectory.cd (s); SString after = currentDirectory.getName(); //fprintf (stderr, "after %*.*s [%*.*s]\n", SSARGS (s), SSARGS(after)); if (after != before) rereadDir (); return; } if (source == fileListBox->textList) { SString s = fileListBox->textList->getLastSelectedText(); fileTextEdit->setText (s); return; } if (source == fileTypeListBox->textList) { SString s = fileTypeListBox->textList->getLastSelectedText(); //fprintf (stderr, "typeselected %*.*s\n", SSARGS(s)); fileTypeChanged (s); } } /** * STextEditLS */ void SFileDialog::textEntered (void *source) { if (source == filterTextEdit) { rereadDir (); } /* ok */ if (source == fileTextEdit) { isCancel = false; hide(); return; } } void SFileDialog::filterChanged () { fileFilter = filterTextEdit->getText(); /* trim what is not there */ while (fileFilter.size()>0 && (fileFilter[0]==' '||fileFilter[0]=='\t')) { fileFilter.remove (0); } while (fileFilter.size()>0 && (fileFilter[fileFilter.size()-1] == ' ' || fileFilter[fileFilter.size()-1] == '\t')) { fileFilter.truncate (fileFilter.size()-1); } //fprintf (stderr,"filter changed to '%*.*s'\n"); } /** * set icon accoring to showHidden */ void SFileDialog::setHidden() { /* create icons here */ const char * str = showHidden?"CircleOn" : "CircleOff"; hiddenButton->setIcon (SIconFactory::getIcon(str)); } bool SFileDialog::close (SPanel* comp) { isCancel =true; hide(); textDialog->hide(); return false; } void SFileDialog::focusChanged (void *source, bool in) { if (!in && source == filterTextEdit) { rereadDir (); } } /** * set the filename - cut off the dirpart */ void SFileDialog::setFileName (const SString& _filename) { SDir d; /* this will chop off filename */ d.cd (_filename); SStringVector v(_filename, "/"); SString fn; if (v.size()) { fn.append (v[v.size()-1]); } currentDirectory = d; rereadDir (); fileTextEdit->setText (fn); fileListBox->selectText (fn); } void SFileDialog::setTitleForeground (const SColor& fg) { textDialog->setTitleForeground (fg); fileTypeButton->setForeground (fg); hiddenButton->setForeground (fg); homeButton->setForeground (fg); cdButton->setForeground (fg); yesButton->setForeground (fg); cancelButton->setForeground (fg); createButton->setForeground (fg); folderTitleLabel->setForeground (fg); fileTitleLabel->setForeground (fg); filterTitleLabel->setForeground (fg); folderListBox->setLabelForeground (fg); fileListBox->setLabelForeground (fg); fileTypeListBox->setLabelForeground (fg); } void SFileDialog::setLabelForeground (const SColor& fg) { textDialog->setLabelForeground (fg); folderNameLabel->setForeground (fg); fileTypeLabel->setForeground (fg); } void SFileDialog::setBackground (const SColor& bg) { SFrame::setBackground (bg); textDialog->setBackground (bg); fileTextEdit->setTextBackground (SColor("white")); filterTextEdit->setTextBackground (SColor("white")); } void SFileDialog::setForeground (const SColor& fg) { SFrame::setForeground (fg); setLabelForeground (fg); setTitleForeground (fg); } void SFileDialog::setSliderBackground (const SColor& bg) { folderListBox->setSliderBackground (bg); fileListBox->setSliderBackground (bg); fileTypeListBox->setSliderBackground (bg); } void SFileDialog::setFont (const SString& font, double fontSize) { textDialog->setFont (font, fontSize); folderNameLabel->setFont (font, fontSize); fileTypeLabel->setFont (font, fontSize); textDialog->setFont (font, fontSize); fileTypeButton->setFont (font, fontSize); hiddenButton->setFont (font, fontSize); homeButton->setFont (font, fontSize); cdButton->setFont (font, fontSize); yesButton->setFont (font, fontSize); cancelButton->setFont (font, fontSize); createButton->setFont (font, fontSize); folderTitleLabel->setFont (font, fontSize); fileTitleLabel->setFont (font, fontSize); filterTitleLabel->setFont (font, fontSize); folderListBox->setFont (font, fontSize); fileListBox->setFont (font, fontSize); fileTypeListBox->setFont (font, fontSize); recalc(); } void SFileDialog::setFontSize (double fontSize) { textDialog->setFontSize (fontSize); folderNameLabel->setFontSize (fontSize); fileTypeLabel->setFontSize (fontSize); textDialog->setFontSize (fontSize); fileTypeButton->setFontSize (fontSize); hiddenButton->setFontSize (fontSize); cdButton->setFontSize (fontSize); yesButton->setFontSize (fontSize); cancelButton->setFontSize (fontSize); createButton->setFontSize (fontSize); folderTitleLabel->setFontSize (fontSize); fileTitleLabel->setFontSize (fontSize); filterTitleLabel->setFontSize (fontSize); folderListBox->setFontSize (fontSize); fileListBox->setFontSize (fontSize); fileTypeListBox->setFontSize (fontSize); recalc(); } /** * keyboard focus lost. */ void SFileDialog::gainedKeyboardFocus (SWindow* w) { if (isFocused) return; isFocused = true; fileTextEdit->setFocus(); }