diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fddb57..63c71f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,7 +135,7 @@ set(DOC_FILES ) # find c++utilities -find_package(c++utilities 3.3.0 REQUIRED) +find_package(c++utilities 4.0.0 REQUIRED) use_cpp_utilities() # find qtutilities @@ -157,6 +157,7 @@ include(JsProviderConfig) include(WebViewProviderConfig) include(WindowsResources) include(AppTarget) +include(ShellCompletion) # create desktop file using previously defined meta data add_desktop_file() diff --git a/application/main.cpp b/application/main.cpp index cd6dc57..de9c7e3 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -51,7 +51,7 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg) : forceIndexPosArg("force", 'f', "forces the specified position even if the file to be rewritten"), indexPosArg("index-pos", '\0', "specifies the preferred index position"), forceRewriteArg("force-rewrite", '\0', "forces the file to rewritten from the scratch"), - valuesArg("fields", 'n', "specifies the values to be set"), + valuesArg("values", 'n', "specifies the values to be set"), setTagInfoArg("set", 's', "sets the values of all specified tag fields") { docTitleArg.setCombinable(true); @@ -61,9 +61,11 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg) : treatUnknownFilesAsMp3FilesArg.setCombinable(true); id3v1UsageArg.setRequiredValueCount(1); id3v1UsageArg.setValueNames({"always/keepexisting/never"}); + id3v1UsageArg.setPreDefinedCompletionValues("always keepexisting never"); id3v1UsageArg.setCombinable(true); id3v2UsageArg.setRequiredValueCount(1); id3v2UsageArg.setValueNames({"always/keepexisting/never"}); + id3v2UsageArg.setPreDefinedCompletionValues("always keepexisting never"); id3v2UsageArg.setCombinable(true); mergeMultipleSuccessiveTagsArg.setCombinable(true); id3v2VersionArg.setRequiredValueCount(1); @@ -71,6 +73,7 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg) : id3v2VersionArg.setCombinable(true); encodingArg.setRequiredValueCount(1); encodingArg.setValueNames({"latin1/utf8/utf16le/utf16be"}); + encodingArg.setPreDefinedCompletionValues("latin1 utf8 utf16le utf16be"); encodingArg.setCombinable(true); removeTargetsArg.setRequiredValueCount(-1); removeTargetsArg.setValueNames({}); @@ -89,19 +92,25 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg) : prefPaddingArg.setValueNames({"preferred padding in byte"}); prefPaddingArg.setCombinable(true); tagPosValueArg.setRequiredValueCount(1); - forceTagPosArg.setCombinable(true); - tagPosArg.setValueNames({"front/back/current"}); + tagPosValueArg.setValueNames({"front/back/current"}); + tagPosValueArg.setPreDefinedCompletionValues("front back current"); + tagPosValueArg.setImplicit(true); + forceTagPosArg.setCombinable(true); tagPosArg.setCombinable(true); tagPosArg.setSubArguments({&tagPosValueArg, &forceTagPosArg}); - indexPosValueArg.setRequiredValueCount(1); forceIndexPosArg.setCombinable(true); - indexPosArg.setValueNames({"front/back/current"}); + indexPosValueArg.setRequiredValueCount(1); + indexPosValueArg.setValueNames({"front/back/current"}); + indexPosValueArg.setPreDefinedCompletionValues("front back current"); + indexPosValueArg.setImplicit(true); indexPosArg.setCombinable(true); indexPosArg.setSubArguments({&indexPosValueArg, &forceIndexPosArg}); forceRewriteArg.setCombinable(true); valuesArg.setValueNames({"title=foo", "album=bar", "cover=/path/to/file"}); valuesArg.setRequiredValueCount(-1); valuesArg.setImplicit(true); + valuesArg.setPreDefinedCompletionValues(Cli::fieldNames); + valuesArg.setValueCompletionBehavior(ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::AppendEquationSign); setTagInfoArg.setDenotesOperation(true); setTagInfoArg.setCallback(std::bind(Cli::setTagInfo, std::cref(*this))); setTagInfoArg.setSubArguments({&valuesArg, &filesArg, &docTitleArg, &removeOtherFieldsArg, &treatUnknownFilesAsMp3FilesArg, &id3v1UsageArg, &id3v2UsageArg, @@ -152,6 +161,7 @@ int main(int argc, char *argv[]) Argument fieldsArg("fields", 'n', "specifies the field names to be displayed"); fieldsArg.setValueNames({"title", "album", "artist", "trackpos"}); fieldsArg.setRequiredValueCount(-1); + fieldsArg.setPreDefinedCompletionValues(Cli::fieldNames); fieldsArg.setImplicit(true); Argument displayTagInfoArg("get", 'g', "displays the values of all specified tag fields (displays all fields if none specified)"); displayTagInfoArg.setDenotesOperation(true); diff --git a/cli/mainfeatures.cpp b/cli/mainfeatures.cpp index 540f89f..c0b4844 100644 --- a/cli/mainfeatures.cpp +++ b/cli/mainfeatures.cpp @@ -152,19 +152,21 @@ void printNotifications(const MediaFileInfo &fileInfo, const char *head = nullpt printNotifications(notifications, head, beVerbose); } -void printFieldNames(const std::vector ¶meterValues) +const char *const fieldNames = "title album artist genre year comment bpm bps lyricist track disk part totalparts encoder\n" + "recorddate performers duration language encodersettings lyrics synchronizedlyrics grouping\n" + "recordlabel cover composer rating description"; + +void printFieldNames(const ArgumentOccurance &occurance) { CMD_UTILS_START_CONSOLE; - VAR_UNUSED(parameterValues) - cout << "title album artist genre year comment bpm bps lyricist track disk part totalparts encoder\n" - "recorddate performers duration language encodersettings lyrics synchronizedlyrics grouping\n" - "recordlabel cover composer rating description" << endl; + VAR_UNUSED(occurance) + cout << fieldNames << endl; } -void removeBackupFiles(const std::vector ¶meterValues, const Argument &recursiveArg) +void removeBackupFiles(const ArgumentOccurance &occurance, const Argument &recursiveArg) { CMD_UTILS_START_CONSOLE; - QDir dir(QString::fromStdString(parameterValues.at(0))); + QDir dir(QString::fromStdString(occurance.values.front())); QStringList affectedFiles; int filesFound = Utility::removeBackupFiles(dir, affectedFiles, &cout, recursiveArg.isPresent()); cout << affectedFiles.size() << " of " << filesFound << " backup files have been removed." << endl; @@ -571,10 +573,9 @@ bool AttachmentInfo::next(AbstractContainer *container) return true; } -void generateFileInfo(const std::vector ¶meterValues, const Argument &inputFileArg, const Argument &outputFileArg, const Argument &validateArg) +void generateFileInfo(const ArgumentOccurance &, const Argument &inputFileArg, const Argument &outputFileArg, const Argument &validateArg) { CMD_UTILS_START_CONSOLE; - VAR_UNUSED(parameterValues) try { // parse tags MediaFileInfo inputFileInfo(inputFileArg.values().front()); @@ -642,7 +643,7 @@ void printProperty(const char *propName, const intType value, const char *suffix } } -void displayFileInfo(const std::vector &, const Argument &filesArg, const Argument &verboseArg) +void displayFileInfo(const ArgumentOccurance &, const Argument &filesArg, const Argument &verboseArg) { CMD_UTILS_START_CONSOLE; if(!filesArg.isPresent() || filesArg.values().empty()) { diff --git a/cli/mainfeatures.h b/cli/mainfeatures.h index fe3db67..03bd5f8 100644 --- a/cli/mainfeatures.h +++ b/cli/mainfeatures.h @@ -43,13 +43,14 @@ struct SetTagInfoArgs ApplicationUtilities::Argument setTagInfoArg; }; -void printFieldNames(const std::vector ¶meterValues); -void displayFileInfo(const std::vector &, const ApplicationUtilities::Argument &filesArg, const ApplicationUtilities::Argument &verboseArg); -void generateFileInfo(const std::vector ¶meterValues, const ApplicationUtilities::Argument &inputFileArg, const ApplicationUtilities::Argument &outputFileArg, const ApplicationUtilities::Argument &validateArg); +extern const char *const fieldNames; +void printFieldNames(const ApplicationUtilities::ArgumentOccurance &occurance); +void displayFileInfo(const ApplicationUtilities::ArgumentOccurance &, const ApplicationUtilities::Argument &filesArg, const ApplicationUtilities::Argument &verboseArg); +void generateFileInfo(const ApplicationUtilities::ArgumentOccurance &, const ApplicationUtilities::Argument &inputFileArg, const ApplicationUtilities::Argument &outputFileArg, const ApplicationUtilities::Argument &validateArg); void displayTagInfo(const ApplicationUtilities::Argument &fieldsArg, const ApplicationUtilities::Argument &filesArg, const ApplicationUtilities::Argument &verboseArg); void setTagInfo(const Cli::SetTagInfoArgs &args); void extractField(const ApplicationUtilities::Argument &fieldsArg, const ApplicationUtilities::Argument &inputFileArg, const ApplicationUtilities::Argument &outputFileArg, const ApplicationUtilities::Argument &verboseArg); -void removeBackupFiles(const std::vector ¶meterValues, const ApplicationUtilities::Argument &recursiveArg); +void removeBackupFiles(const ApplicationUtilities::ArgumentOccurance &occurance, const ApplicationUtilities::Argument &recursiveArg); }