Added a new command and fixed a crash bug

Created a new client command called 'ls_cmds' that will
list all available commands. This more like a revival of
an old command that existed in the past. It's function
was once added to 'about' but now it has been re-spun
into it's own command once again.

Fixed a bug that caused the 'connect' command to crash
the client after calling it with the '-save' option and
then the 'ls_cmds' command. The connect command actual
creates a SaveBookmark command object when called with
the '-save' option. The problem was its constructor was
replacing it's existing object pointer in the command
list with a pointer that was about to get destroyed
after calling the '-save' option, causing the command
object list to contain a null pointer for save_bookmark.
This commit is contained in:
Maurice ONeal 2020-03-30 12:23:21 -04:00
parent 3f39ba8767
commit 347e01eeff
7 changed files with 107 additions and 53 deletions

View File

@ -20,7 +20,10 @@ SaveBookmark::SaveBookmark(QObject *parent) : Command(parent)
{
setObjectName("save_bookmark");
if (!Shared::clientCmds->contains(objectName()))
{
Shared::clientCmds->insert(objectName(), this);
}
}
QString SaveBookmark::shortText() {return tr("create or update a host bookmark.");}
@ -76,8 +79,8 @@ void SaveBookmark::run(const QString &name, QStringList &args)
if (file.open(QFile::WriteOnly | QFile::Truncate))
{
QString addr = getParam("-addr", args);
int port = getParam("-port", args).toInt();
auto addr = getParam("-addr", args);
auto port = getParam("-port", args).toInt();
if (addr.isEmpty()) addr = *Shared::hostAddress;
if (port == 0) port = *Shared::hostPort;
@ -124,9 +127,9 @@ void SaveBookmark::dataIn(const QString &argsLine)
}
else
{
QStringList args = parseArgs(argsLine);
bool force = argExists("-force", args);
QString name = getParam("-name", args);
auto args = parseArgs(argsLine);
auto force = argExists("-force", args);
auto name = getParam("-name", args);
if (name.isEmpty())
{
@ -173,8 +176,8 @@ void ListBookmarks::dataIn(const QString &argsLine)
void DeleteBookmark::dataIn(const QString &argsLine)
{
QStringList args = parseArgs(argsLine);
QString name = getParam("-name", args);
auto args = parseArgs(argsLine);
auto name = getParam("-name", args);
if (name.isEmpty())
{
@ -182,7 +185,7 @@ void DeleteBookmark::dataIn(const QString &argsLine)
}
else
{
QString path = appDataDir() + BOOKMARK_FOLDER + "/" + name + ".json";
auto path = appDataDir() + BOOKMARK_FOLDER + "/" + name + ".json";
if (!QFile::remove(path))
{
@ -193,8 +196,8 @@ void DeleteBookmark::dataIn(const QString &argsLine)
void SeeBookmark::dataIn(const QString &argsLine)
{
QStringList args = parseArgs(argsLine);
QString name = getParam("-name", args);
auto args = parseArgs(argsLine);
auto name = getParam("-name", args);
if (name.isEmpty())
{
@ -202,13 +205,13 @@ void SeeBookmark::dataIn(const QString &argsLine)
}
else
{
QString path = appDataDir() + BOOKMARK_FOLDER + "/" + name + ".json";
auto path = appDataDir() + BOOKMARK_FOLDER + "/" + name + ".json";
QFile file(path, this);
if (file.open(QFile::ReadOnly))
{
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
auto doc = QJsonDocument::fromJson(file.readAll());
cacheTxt(TEXT, "address: " + doc.object().value("address").toString() + "\n");
cacheTxt(TEXT, "port: " + QString::number(doc.object().value("port").toInt()) + "\n");

View File

@ -89,13 +89,18 @@ QString Resume::longText() {return TXT_Term;}
void Connect::dataIn(const QString &argsLine)
{
QStringList args = parseArgs(argsLine);
auto args = parseArgs(argsLine);
*Shared::hostAddress = getParam("-addr", args);
*Shared::hostPort = getParam("-port", args).toUShort();
QString saveName = getParam("-save", args);
QString loadName = getParam("-load", args);
auto saveName = getParam("-save", args);
auto loadName = getParam("-load", args);
if (*Shared::hostPort == 0)
{
*Shared::hostPort = DEFAULT_PORT;
}
if (!saveName.isEmpty())
{
@ -108,7 +113,7 @@ void Connect::dataIn(const QString &argsLine)
if (file.open(QFile::ReadOnly))
{
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
auto doc = QJsonDocument::fromJson(file.readAll());
*Shared::hostAddress = doc.object().value("address").toString();
*Shared::hostPort = static_cast<quint16>(doc.object().value("port").toInt());
@ -129,10 +134,6 @@ void Connect::dataIn(const QString &argsLine)
{
cacheTxt(ERR, "err: '" + *Shared::hostAddress + "' is not a valid address.\n");
}
else if (*Shared::hostPort == 0)
{
cacheTxt(ERR, "err: The host port cannot be 0.\n");
}
else
{
emit connectToHost();

View File

@ -24,10 +24,21 @@ About::About(QObject *parent) : Command(parent)
}
void About::onStartup() {dataIn(QString());}
QString About::shortText() {return tr("display information about this MRCI client and display all available commands.");}
QString About::shortText() {return tr("display information about the client or a command.");}
QString About::ioText() {return tr("[{cmd_name}]/[text]");}
QString About::longText() {return TXT_About;}
ListCmds::ListCmds(QObject *parent) : Command(parent)
{
setObjectName("ls_cmds");
Shared::clientCmds->insert(objectName(), this);
}
QString ListCmds::shortText() {return tr("display all available commands.");}
QString ListCmds::ioText() {return tr("[none]/[text]");}
QString ListCmds::longText() {return TXT_ListCmds;}
void About::dispInfo(Command *cmdObj)
{
QString txt;
@ -86,25 +97,13 @@ bool About::dispInfo(const QString &cmdName)
}
}
void About::listCmds(QHash<QString, Command *> *cmdObjs, QTextStream &txtOut, int largestCmd)
{
QStringList cmdNames = cmdObjs->keys();
cmdNames.sort(Qt::CaseInsensitive);
for (int i = 0; i < cmdNames.size(); ++i)
{
wordWrap(cmdNames[i].leftJustified(largestCmd, ' ') + " - ", txtOut, cmdObjs->value(cmdNames[i])->shortText(), Shared::mainWidget);
}
}
void About::dataIn(const QString &argsLine)
{
QStringList args = parseArgs(argsLine);
auto args = parseArgs(argsLine);
if (args.size() > 0)
{
QString cmdName = args[0].toLower().trimmed();
auto cmdName = args[0].toLower().trimmed();
if (!dispInfo(cmdName))
{
@ -120,21 +119,8 @@ void About::dataIn(const QString &argsLine)
txtOut << "Based on QT " << QT_VERSION_STR << " " << 8 * QT_POINTER_SIZE << "bit" << endl << endl;
txtOut << "The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE" << endl;
txtOut << "WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE." << endl << endl;
txtOut << "usage: <command> <arguments>" << endl << endl;
txtOut << "<command>" << endl << endl;
QStringList cmdNames = Shared::clientCmds->keys() + Shared::hostDocs->keys();
int largestCmd = 0;
for (int i = 0; i < cmdNames.size(); ++i)
{
if (cmdNames[i].size() > largestCmd) largestCmd = cmdNames[i].size();
}
listCmds(Shared::clientCmds, txtOut, largestCmd);
listCmds(Shared::hostDocs, txtOut, largestCmd);
txtOut << endl << endl << "for more detailed information about a command type: about <command>" << endl << endl;
txtOut << "run: 'ls_cmds' to see all available commands." << endl << endl;
txtOut << "for more detailed information about a command run: 'about <command>'" << endl << endl;
cacheTxt(TEXT, txt);
}
@ -144,3 +130,40 @@ void About::run()
{
dataIn(QString());
}
void ListCmds::ls(QHash<QString, Command *> *cmdObjs, QTextStream &txtOut, const QString &title)
{
if (!cmdObjs->isEmpty())
{
auto cmdNames = cmdObjs->keys();
auto largestCmd = 0;
for (int i = 0; i < cmdNames.size(); ++i)
{
if (cmdNames[i].size() > largestCmd) largestCmd = cmdNames[i].size();
}
cmdNames.sort(Qt::CaseInsensitive);
txtOut << endl;
txtOut << title << endl << endl;
for (int i = 0; i < cmdNames.size(); ++i)
{
wordWrap(cmdNames[i].leftJustified(largestCmd, ' ') + " - ", txtOut, cmdObjs->value(cmdNames[i])->shortText(), Shared::mainWidget);
}
}
}
void ListCmds::dataIn(const QString &argsLine)
{
Q_UNUSED(argsLine)
QString txt;
QTextStream txtOut(&txt);
ls(Shared::clientCmds, txtOut, "Client Commands:");
ls(Shared::hostDocs, txtOut, "Host Commands:");
cacheTxt(TEXT, txt);
}

View File

@ -28,7 +28,6 @@ class About : public Command
private:
void dispInfo(Command *cmdObj);
void listCmds(QHash<QString, Command *> *cmdObjs, QTextStream &txtOut, int largestCmd);
bool dispInfo(const QString &cmdName);
bool dispClientCmd(const QString &cmdName);
bool dispHostCmd(const QString &cmdName);
@ -49,4 +48,27 @@ public slots:
void onStartup();
};
//--------------------------
class ListCmds : public Command
{
Q_OBJECT
private:
void ls(QHash<QString, Command *> *cmdObjs, QTextStream &txtOut, const QString &title);
public:
QString shortText();
QString ioText();
QString longText();
explicit ListCmds(QObject *parent = nullptr);
public slots:
void dataIn(const QString &argsLine);
};
#endif // INFO_H

View File

@ -71,4 +71,7 @@ set or view the maximum amount of lines of text that can be displayed in this ap
to set this limit or leave it out to display what the limit is currently set at. this has a minimum value \
of 50 and a maxmum of 100000."
#define TXT_ListCmds "\
list all commands currently available for runnning (host and client)."
#endif // LONG_TXT_H

View File

@ -70,12 +70,13 @@
#define DEFAULT_HIST_LIMIT 100
#define DEFAULT_MAX_LINES 1000
#define RDBUFF 16777215
#define DEFAULT_PORT 35516
#define TXT_CODEC "UTF-16LE"
#define BOOKMARK_FOLDER "bookmarks"
#define CONFIG_FILENAME "config_v3.json"
#define APP_NAME "Cmdr"
#define APP_TARGET "cmdr"
#define APP_VERSION "3.0"
#define APP_VERSION "3.1"
enum TypeID : quint8
{

View File

@ -118,6 +118,7 @@ int main(int argc, char *argv[])
new SetFont(&app);
new SetMaxLines(&app);
new Genfile(&app);
new ListCmds(&app);
setupClientCmds();
setupCmdLine();