diff --git a/compress_gob.cpp b/compress_gob.cpp index 5216f733..1b16706e 100644 --- a/compress_gob.cpp +++ b/compress_gob.cpp @@ -40,7 +40,7 @@ CompressGob::CompressGob(const std::string &name) : CompressionTool(name, TOOLTY _chunks = NULL; ToolInput input; - input.format = "*.*"; + input.format = "*.stk"; _inputPaths.push_back(input); _shorthelp = "Compresses Gobliiins! files data files."; diff --git a/compress_kyra.cpp b/compress_kyra.cpp index 3c1cc54e..a2363316 100644 --- a/compress_kyra.cpp +++ b/compress_kyra.cpp @@ -36,6 +36,15 @@ CompressKyra::CompressKyra(const std::string &name) : CompressionTool(name, TOOL _helptext = "\nUsage: " + getName() + " [mode params] [-o outfile] \n"; } +InspectionMatch CompressKyra::inspectInput(const Filename &filename) { + if (filename.hasExtension("VRM") || + filename.hasExtension("PAK") || + filename.hasExtension("TLK") || + filename.hasExtension("AUD")) + return IMATCH_PERFECT; + return IMATCH_AWFUL; +} + void CompressKyra::execute() { Filename inpath(_inputPaths[0].path); Filename &outpath = _outputPath; diff --git a/compress_kyra.h b/compress_kyra.h index 7d962d61..02a20d2d 100644 --- a/compress_kyra.h +++ b/compress_kyra.h @@ -31,6 +31,8 @@ public: virtual void execute(); + virtual InspectionMatch inspectInput(const Filename &filename); + protected: struct DuplicatedFile; diff --git a/compress_saga.cpp b/compress_saga.cpp index 329a5ca9..39f56137 100644 --- a/compress_saga.cpp +++ b/compress_saga.cpp @@ -124,8 +124,13 @@ CompressSaga::CompressSaga(const std::string &name) : CompressionTool(name, TOOL _helptext = "\nUsage: " + getName() +" [mode] [mode params] [-o outputfile = infile.cmp] \n"; } -bool CompressSaga::inspectInput(const Filename &filename) { - return filename.hasExtension("rsc") || filename.hasExtension("res") || filename.hasExtension("bin") || filename.getFullName() == "inherit the earth voices"; +InspectionMatch CompressSaga::inspectInput(const Filename &filename) { + if (filename.hasExtension("rsc") || + filename.hasExtension("res") || + filename.hasExtension("bin") || + filename.getFullName() == "inherit the earth voices") + return IMATCH_PERFECT; + return IMATCH_AWFUL; } // -------------------------------------------------------------------------------- diff --git a/compress_saga.h b/compress_saga.h index 2d17b545..1f64981e 100644 --- a/compress_saga.h +++ b/compress_saga.h @@ -44,10 +44,10 @@ enum SAGAGameType { class CompressSaga : public CompressionTool { public: CompressSaga(const std::string &name = "compress_saga"); - - virtual bool inspectInput(const Filename &filename); virtual void execute(); + + virtual InspectionMatch inspectInput(const Filename &filename); // Declarations should be inside the class to prevent linker errors diff --git a/extract_cine.h b/extract_cine.h index 653069da..c7d1ad00 100644 --- a/extract_cine.h +++ b/extract_cine.h @@ -1,3 +1,25 @@ +/* Scumm Tools + * Copyright (C) 2009 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + #ifndef EXTRACT_CINE_H #define EXTRACT_CINE_H diff --git a/extract_scumm_mac.cpp b/extract_scumm_mac.cpp index 5491ef00..232fea83 100644 --- a/extract_scumm_mac.cpp +++ b/extract_scumm_mac.cpp @@ -23,6 +23,8 @@ #include "extract_scumm_mac.h" +#include + /* this makes extract_scumm_mac convert extracted file names to lower case */ #define CHANGECASE @@ -39,6 +41,15 @@ ExtractScummMac::ExtractScummMac(const std::string &name) : Tool(name, TOOLTYPE_ _shorthelp + "\n"; } +InspectionMatch ExtractScummMac::inspectInput(const Filename &filename) { + std::string name = filename.getFullName(); + std::transform(name.begin(), name.end(), name.begin(), tolower); + std::string::size_type pos = name.find("data"); + if (pos == name.length() - 4) // True if the file name ends with "Data" + return IMATCH_PERFECT; + return IMATCH_AWFUL; +} + void ExtractScummMac::execute() { unsigned long file_record_off, file_record_len; unsigned long file_off, file_len; diff --git a/extract_scumm_mac.h b/extract_scumm_mac.h index 84a9a8e1..fa29b15b 100644 --- a/extract_scumm_mac.h +++ b/extract_scumm_mac.h @@ -31,6 +31,8 @@ public: ExtractScummMac(const std::string &name = "extract_scumm_mac"); virtual void execute(); + + virtual InspectionMatch inspectInput(const Filename &filename); }; #endif diff --git a/gui/gui_tools.cpp b/gui/gui_tools.cpp index 7b3f4710..9b2d456c 100644 --- a/gui/gui_tools.cpp +++ b/gui/gui_tools.cpp @@ -62,15 +62,11 @@ wxArrayString ToolsGUI::getToolList(ToolType tt) const { } wxArrayString ToolsGUI::getToolList(const Filename &filename, ToolType tt) const { + ToolList choices = inspectInput(filename, tt); wxArrayString l; - for (std::map::const_iterator tool = _toolmap.begin(); tool != _toolmap.end(); ++tool) { - if (tt == TOOLTYPE_ALL || tool->second->getType() == tt) { - if(tool->second->inspectInput(filename)) { - l.Add(tool->second->getName()); - } - } - } + for (ToolList::const_iterator tool = choices.begin(); tool != choices.end(); ++tool) + l.Add(wxString((*tool)->getName().c_str(), wxConvUTF8)); l.Sort(); std::unique(l.begin(), l.end()); @@ -105,10 +101,6 @@ ToolGUI::~ToolGUI() { //delete _backend; } -bool ToolGUI::inspectInput(const Filename &filename) const { - return _backend->inspectInput(filename); -} - ToolInputs ToolGUI::getInputList() const { return _backend->_inputPaths; } diff --git a/gui/gui_tools.h b/gui/gui_tools.h index 9664c993..899a79cc 100644 --- a/gui/gui_tools.h +++ b/gui/gui_tools.h @@ -64,14 +64,6 @@ public: */ void addGame(const wxString &game_name); - /** - * Returns true if the file appears to be valid input to this tool. - * - * @param filename The file to inspect. - * @return True if we can possibly parse this file. - */ - bool inspectInput(const Filename &filename) const; - /** * Returns the list of valid inputs of this tool, along with the * paths already set (if applicable) diff --git a/gui/main.cpp b/gui/main.cpp index 58615d4a..8615f744 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -116,7 +116,7 @@ ScummToolsFrame::ScummToolsFrame(const wxString &title, const wxPoint &pos, cons sizer->Add(linepanel, wxSizerFlags().Expand().Center().Border()); // Buttons on the bottom - _buttons = new WizardButtons(main, linetext); + _buttons = new WizardButtons(main, linetext, _configuration); sizer->Add(_buttons, wxSizerFlags().Border().Center().Expand()); main->SetSizer(sizer); @@ -178,8 +178,9 @@ BEGIN_EVENT_TABLE(WizardButtons, wxPanel) EVT_BUTTON(ID_CANCEL, WizardButtons::onClickCancel) END_EVENT_TABLE() -WizardButtons::WizardButtons(wxWindow *parent, wxStaticText *linetext) +WizardButtons::WizardButtons(wxWindow *parent, wxStaticText *linetext, Configuration &conf) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, wxT("WizardButtonPanel")), + _configuration(conf), _linetext(linetext), _currentPage(NULL) { @@ -223,7 +224,11 @@ void WizardButtons::reset() { enablePrevious(true); showFinish(false); showAbort(false); - setLineLabel(wxT("ScummVM Tools")); + + wxString label(wxT("ScummVM Tools")); + if (_configuration.selectedTool) + label << wxT(" - ") << _configuration.selectedTool->getName(); + setLineLabel(label); } void WizardButtons::setPage(WizardPage *current, wxWindow *panel) { diff --git a/gui/main.h b/gui/main.h index fafeb945..d83fc174 100644 --- a/gui/main.h +++ b/gui/main.h @@ -107,8 +107,9 @@ public: * * @param parent The parent window * @param linetext A static text that is used to display some extra information + * @param conf The configuration object used for the tools */ - WizardButtons(wxWindow *parent, wxStaticText *linetext); + WizardButtons(wxWindow *parent, wxStaticText *linetext, Configuration &conf); /* Set the buttons to the standard configuration * (prev, next shown and enabled, finish disabled) @@ -161,17 +162,19 @@ public: void onClickCancel(wxCommandEvent &e); protected: - /** 'Next' (or finish) button */ + /** Configuration used by the Wizard. */ + Configuration &_configuration; + /** 'Next' (or finish) button. */ wxButton *_next; - /** 'Previous' button */ + /** 'Previous' button. */ wxButton *_prev; - /** 'Cancel' button */ + /** 'Cancel' button. */ wxButton *_cancel; - /** The static text on the line seperating the page area and the buttons */ + /** The static text on the line seperating the page area and the buttons. */ wxStaticText *_linetext; - /** Current page, required for dumping events to it */ + /** Current page, required for dumping events to it. */ WizardPage *_currentPage; - /** Current panel, required so we can pass it as arguments to the handlers */ + /** Current panel, required so we can pass it as arguments to the handlers. */ wxWindow *_currentPanel; DECLARE_EVENT_TABLE() diff --git a/gui/pages.cpp b/gui/pages.cpp index d405b70d..105a8f46 100644 --- a/gui/pages.cpp +++ b/gui/pages.cpp @@ -239,7 +239,6 @@ void ChooseToolPage::onChangeTool(wxCommandEvent &evt) { wxStaticText *text = dynamic_cast(tool->GetParent()->FindWindowByName(wxT("ToolText"))); text->SetLabel(g_tools[tool->GetStringSelection()].getShortHelp()); - //text->Wrap(text->GetParent()->GetSize().GetWidth()); } // Common base class for the IO pages @@ -377,10 +376,12 @@ void ChooseInPage::onNext(wxWindow *panel) { } else { wxArrayString ls = g_tools.getToolList(filename, _configuration.compressing? TOOLTYPE_COMPRESSION : TOOLTYPE_EXTRACTION); - if(ls.size() == 1) + if(ls.size() == 1) { + _configuration.selectedTool = g_tools.get(ls[0]); switchPage(new ChooseOutPage(_topframe)); - else + } else { switchPage(new ChooseToolPage(_topframe, ls)); + } } } @@ -510,8 +511,8 @@ wxWindow *ChooseOutPage::CreatePanel(wxWindow *parent) { // some help perhaps? sizer->Add(new wxStaticText(panel, wxID_ANY, - wxT("Select an output directory.\n\n") - wxT("Note: Some tools display file picker here, this should perhaps be changed to always ") + wxT("Select an output directory (using tool ") + _configuration.selectedTool->getName() + wxT(").\n\n") + + wxT("Note: Some tools display file picker here, this should perhaps be changed to always ") + wxT("be directory output, since often don't want to name the output file.)") ), wxSizerFlags(1).Expand()); @@ -521,21 +522,22 @@ wxWindow *ChooseOutPage::CreatePanel(wxWindow *parent) { sizer->AddSpacer(10); // Create output selection + wxSizer *colsizer = new wxBoxSizer(wxHORIZONTAL); if (tool.outputToDirectory()) { wxStaticBoxSizer *box = new wxStaticBoxSizer(wxHORIZONTAL, panel, wxT("Destination folder")); - + wxDirPickerCtrl *picker = new wxDirPickerCtrl( panel, wxID_ANY, _configuration.outputPath, wxT("Select a folder"), wxDefaultPosition, wxSize(300, -1), wxFLP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST, wxDefaultValidator, wxT("OutputPicker")); - box->Add(picker); + box->Add(picker, wxSizerFlags(1).Expand()); panel->Connect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(ChooseIOPage::onSelectFile), NULL, this); picker->SetPath(_configuration.outputPath); - sizer->Add(box); + colsizer->Add(box, wxSizerFlags(2).Expand()); } else { wxStaticBoxSizer *box = new wxStaticBoxSizer(wxHORIZONTAL, panel, wxT("Destination file")); @@ -545,14 +547,17 @@ wxWindow *ChooseOutPage::CreatePanel(wxWindow *parent) { wxDefaultPosition, wxSize(300, -1), wxFLP_USE_TEXTCTRL | wxFLP_OVERWRITE_PROMPT | wxFLP_SAVE, wxDefaultValidator, wxT("OutputPicker")); - box->Add(picker); + box->Add(picker, wxSizerFlags(1).Expand()); panel->Connect(wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler(ChooseIOPage::onSelectFile), NULL, this); picker->SetPath(_configuration.outputPath); - sizer->Add(box); + colsizer->Add(box, wxSizerFlags(2).Expand()); } + colsizer->Add(20, 20, 1, wxEXPAND); + sizer->Add(colsizer, wxSizerFlags(0).Expand()); + SetAlignedSizer(panel, sizer); return panel; diff --git a/tool.cpp b/tool.cpp index 96916605..8d29eaea 100644 --- a/tool.cpp +++ b/tool.cpp @@ -158,12 +158,13 @@ void Tool::run() { execute(); } -bool Tool::inspectInput(const Filename &filename) { +InspectionMatch Tool::inspectInput(const Filename &filename) { for (ToolInputs::iterator iter = _inputPaths.begin(); iter != _inputPaths.end(); ++iter) { std::string p = iter->format; if (p == "/") { - // Directory, we don't handle this yet, display all tools - return true; + // TODO + // Directory, we don't handle this yet, don't display at all + return IMATCH_AWFUL; } Filename cmp_filename = p; @@ -171,24 +172,24 @@ bool Tool::inspectInput(const Filename &filename) { if (cmp_filename.getName() == "*") { if (cmp_filename.getExtension() == "*") // Match anything! - return true; + return IMATCH_POSSIBLE; else if (scumm_stricmp(cmp_filename.getExtension().c_str(), filename.getExtension().c_str()) == 0) // Extensions are the same - return true; + return IMATCH_PERFECT; } else { // Match on filename if (cmp_filename.getName() == filename.getName()) { if (cmp_filename.getExtension() == "*") - return true; + return IMATCH_PERFECT; else if (scumm_stricmp(cmp_filename.getExtension().c_str(), filename.getExtension().c_str()) == 0) // Filenames are identical - return true; + return IMATCH_PERFECT; } } } // Didn't match any of our inputs - return false; + return IMATCH_AWFUL; } void Tool::setPrintFunction(void (*f)(void *, const char *), void *udata) { diff --git a/tool.h b/tool.h index c37c5f28..7ff2f722 100644 --- a/tool.h +++ b/tool.h @@ -39,6 +39,19 @@ enum ToolType { TOOLTYPE_ALL, }; +/** + * Return type of the inspectInput function, perfect match means we know we can + * parse this file, possible means we might be able to, Awful means we most likely + * can't read this file. + * If there are perfect results, those are displayed first, if there are none, + * possible results are displayed and finally awful results are dispalyed. + */ +enum InspectionMatch { + IMATCH_PERFECT, + IMATCH_POSSIBLE, + IMATCH_AWFUL, +}; + /** * Describes a possible input to the tool (since some take two seperate files, * some a dir and some a single file. @@ -86,7 +99,7 @@ public: * * @param filename The file to inspect */ - virtual bool inspectInput(const Filename &filename); + virtual InspectionMatch inspectInput(const Filename &filename); /** * Aborts executing of the tool, can be called from another thread diff --git a/tools.cpp b/tools.cpp index f6d1590d..d502e44e 100644 --- a/tools.cpp +++ b/tools.cpp @@ -90,14 +90,28 @@ Tools::~Tools() { delete *iter; } -Tools::ToolList Tools::inspectInput(ToolType type, const Filename &filename) const { - ToolList choices; +Tools::ToolList Tools::inspectInput(const Filename &filename, ToolType type) const { + ToolList perfect_choices; + ToolList good_choices; + ToolList awful_choices; + for (ToolList::const_iterator tool = _tools.begin(); tool != _tools.end(); ++tool) { if (type == TOOLTYPE_ALL || (*tool)->getType() == type) { - if((*tool)->inspectInput(filename)) { - choices.push_back(*tool); - } + InspectionMatch m = (*tool)->inspectInput(filename); + + if (m == IMATCH_PERFECT) + perfect_choices.push_back(*tool); + else if (m == IMATCH_POSSIBLE) + good_choices.push_back(*tool); + else + awful_choices.push_back(*tool); } } - return choices; + + if (perfect_choices.size() > 0) + return perfect_choices; + if (good_choices.size() > 0) + return good_choices; + + return awful_choices; } diff --git a/tools.h b/tools.h index 8fe139fa..eb5f47f4 100644 --- a/tools.h +++ b/tools.h @@ -43,7 +43,7 @@ public: * Returns a list of the tools that supports opening the input file * specified in the input list. */ - ToolList inspectInput(ToolType type, const Filename &filename) const; + ToolList inspectInput(const Filename &filename, ToolType type = TOOLTYPE_ALL) const; protected: /** List of all tools */