How to compare strings using QString and Qt::MatchFlags for Qt5 and up

The Qt QString class is missing a really great opportunity to use the same Qt::MatchFlags that are used elsewhere in Qt. In the interest of making it super easy to add this functionality to my existing code and yours, just copy the following code into one of your commonly used header files. Make sure to actually include the required headers as shown in the comments. Then you can match your strings using Qt::MatchFlags.


/** determine if the pattern matches the string using Qt::MatchFlags
    \param str the string
    \param pattern the pattern to find
    \param flags any combination of the follow Qt flags
                - Qt::MatchFixedString
                - Qt::MatchContains
                - Qt::MatchStartsWith
                - Qt::MatchEndsWith
                - Qt::MatchRegExp (overrides all flags above)
                - Qt::MatchCaseSensitive
    \returns true if the pattern is found in the string

    requires:
    #include <QString>
    #include <QRegularExpression>
    #include <QRegularExpressionMatch>

    Thank you for visiting sirspot.com
    This code is not guaranteed to work.
    Use at your own risk.
*/
static bool QString_Matches(
    const QString& str,
    const QString& pattern,
    const Qt::MatchFlags& flags = (Qt::MatchCaseSensitive | Qt::MatchFixedString))
{
    if(flags.testFlag(Qt::MatchRegExp) == true)
    {
        QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
        if(flags.testFlag(Qt::MatchCaseSensitive) == false)
        {
            options = QRegularExpression::CaseInsensitiveOption;
        }
        QRegularExpression regex(pattern, options);
        return regex.match(str).hasMatch();
    }
    else
    {
        Qt::CaseSensitivity cs = Qt::CaseSensitive;
        if(flags.testFlag(Qt::MatchCaseSensitive) == false)
        {
            cs = Qt::CaseInsensitive;
        }
        if(flags.testFlag(Qt::MatchContains) == true)
        {
            return str.contains(pattern, cs);
        }
        else
        {
            if(flags.testFlag(Qt::MatchStartsWith) == true)
            {
                if(str.startsWith(pattern, cs) == true)
                {
                    return true;
                }
            }
            if(flags.testFlag(Qt::MatchEndsWith) == true)
            {
                if(str.endsWith(pattern, cs) == true)
                {
                    return true;
                }
            }
            if(flags.testFlag(Qt::MatchFixedString) == true)
            {
                return (str.compare(pattern, cs) == 0);
            }
        }
    }
    return false;
};

Happy String Matching!

VLC Media Player with Telnet (TCP) Control

This post is going to take some time to develop properly.  Here is what to do for those who understand how:

  1. open a command prompt with administrative privileges
  2. change directory to where your VLC exe is found
  3. execute the following command
    vlc -I ntservice --ntservice-install --ntservice-extraintf=telnet --telnet-host=131.185.1.1:4212 --telnet-password=12345
  4. Note: set the ip address to your IP or try 0.0.0.0 if you want to work with all interfaces.  Also, the password is required to make the telnet server work so either keep it as 12345 or select your own.
  5. open a telnet client and connect to TCP port 4212

What is missing?  You may need to enter some firewall rules.  You may need to set some additional configuration options such as which IP to bind to, the port to use, etc.  I’ll try to provide more detailed configuration steps sometime in the future.

Good luck!

 

Is Climate Change and Global Warming Fake News?

It’s really not fake news. The global average temperature is definitely on the rise. What could be considered fake news is how much humans have contributed to the rise in temperature. This is difficult, but not impossible to determine. I think the correlation of the data charted on these two sites is very telling.

https://climate.nasa.gov/climate_resources/24/

https://climate.nasa.gov/vital-signs/global-temperature/

So Yes, global warming is real and humans are responsible.  The next question is, “will it stop or can it be stopped?”  That’s a much harder question to answer!

How to fix Git for Windows login error via HTTPS

There are a lot of ways to login to a Git server, which means there are a lot of ways to also fail. I have a suggestion for you if, after trying everything else, you are still getting this error:

remote: invalid username or password. if you log in via a third party service you must ensure you have an account password set in your account profile.

Open a command prompt as administrator and enter the following commands:

git config –global –unset credential.helper

git config –system –unset credential.helper

Make sure you do both.

Now attempt to pull from the server again. This time you should be asked for your user name and password. Make sure you use the username that is in the URL of your request. For example, in this URL: https://gituser@sirspot.com the user name is gituser.

I hope this helped!

 

Hour of Code

Last year I went to 3 schools for Hour of Code.  This year I have already been to 3 schools and am schedule to visit 2 more schools before the end of the week.  The students range in age from 6 years old to 13 years old.  I tailor my presentation to each class based on how responsive the students are.  It is a lot of fun!  If you don’t know what Hour of Code is, you can visit the official site here: https://code.org/learn but basically it is just a week out of the year when we try to get students interested in computer programming.  Have a great week and give the Hour of Code a try!

Qt 5.7 Designer Hangs and Causes VS2013 to Hang

Apparently designer.exe hangs if the new webengine dlls are present.  The dlls can be removed, but then, what if you need them?  The easiest way around this problem for me was to use the mingw Qt 5.7 binaries for designer.exe (without including webengine) and leave the vs2013 binaries alone.  I’m sure Qt will be fixed soon, but this will get you rolling in the mean time.  Happy Coding!

Possibly the best Linux find command examples

If you have been looking for a file on Mac OS X or Linux or Unix, you want to use the “find” command. The problem with the find command is that the usage information at the command line is just terrible. The solution is to bookmark this awesome website:
http://www.thegeekstuff.com/2009/03/15-practical-linux-find-command-examples/

Here are some of my favorites:

Find a file by name in any directory starting with the root path

find / -name passwd

Find a file by name (case-insensitive) starting at the current directory and then run the command md5sum on each file that matches.

find -iname "MyCProgram.c" -exec md5sum {} \;

Find files starting in your home directory that are larger than 100 megatbytes.

find ~ -size +100M

And last, but not least, create an alias for a find command that will remove all files named “a.out” starting from the current directory

alias rmao="find . -iname a.out -exec rm {} \;"
rmao

Happy Hunting!

How to make Mac OS X and MySQL happy with Qt

Using shared libraries on Mac OS X is one of the things that is actually a lot harder than on Windows.  For example, you cannot just put the shared library for MySQL into your path or into the working directory. You have to change the plugin file itself to make it look in the correct location. You find the current value using the command “otool” and change the value using the command “install_name_tool”. Here is an example:

cd Qt/5.4/clang_64/plugins/sqldrivers/

otool -L libqsqlmysql.dylib 

libqsqlmysql.dylib:
libqsqlmysql.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/mysql55/mysql/libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
...

install_name_tool -change /opt/local/lib/mysql55/mysql/libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.20.dylib ./libqsqlmysql.dylib 

otool -L libqsqlmysql.dylib 

libqsqlmysql.dylib:
libqsqlmysql.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/local/mysql/lib/libmysqlclient.20.dylib (compatibility version 18.0.0, current version 18.0.0)
...

Organized C code – Part 1 – The Headers

This is a step-by-step guide to writing code in C and keeping it organized as you go.  It will help you write code that can be reused on multiple projects and hardware platforms.  I will explain some of the finer details along the way so, technically, you don’t even need to know how to program in C to use this guide.

This first part will just go through some templates that every set of C header files will start with.  These header files are used to pre-define the C code you will be writing in a future part of this guide.  That is it for the introductions, now on to your first step writing organized C code!

Step 1

Create a directory for your files with two subdirectories: include and src.  For example, my directory structure looks like this:

directory structure

organized/
organized/include/
organized/src/

The include directory will store all of your header (.h) files and the src directory will store all of your source (.c) files.  These are the files that the C compiler will use to generate machine code (binary language) for your computer.  The C compiler has a “preprocessor” that will look through the code and make changes before attempting to generate machine code.  The C preprocessor is your friend and I will refer to it often.

Step 2

If you need a program to write files, I suggest Microsoft’s Visual Studio Code available here.

Create a text file for the public header that ends with .h to indicate it is a header file.  Save this file in your include directory. For example, the path to my file is:

organized/include/organized.h

snap_2016-10-04_13h51m22s_003_organized-h-visual-studio-code

Paste the following code into your file.  This is the code needed for every header file.  Each time you use this code, replace “ORGANIZED_H” with something that matches your file name.  The only requirement is that you make it unique.  The same name cannot be defined by any other code within a project that uses this header file and I will explain why below.

#ifndef ORGANIZED_H
#define ORGANIZED_H
#ifdef __cplusplus
extern "C" {
#endif
// public header code goes here
#ifdef __cplusplus
}
#endif
#endif // ORGANIZED_H
// empty line

Here are details on this template line by line:

  1. #ifndef is a command used by the C preprocessor that means “If not defined”.  It is used here to check for the name that uniquely identifies this header file so that the entire file can be skipped if it has already been included in the project.  There are other ways to do this, but this method is the only one that is supported by ALL C compilers.
  2. #define is a command used by the C preprocessor that means “Define this value”.  It is used here to define the name you have chosen, which means the next time this header file is included somewhere in the project, the name will already be defined.
  3. #ifdef is a command used by the C preprocessor that means “If defined”.  It is used here to check if the compiler is actually a C++ compiler.  A C++ compiler can do everything a C compiler can do (and more), but it likes to keep things separate.  That is why we will add some code only if this is a C++ compiler.
  4. extern is a keyword that tells the compiler the following code should be made available throughout the program and not just to this file.  It is used here because a C++ compiler was detected at line 3 and we want all of our header code to be made available to C and C++ alike.  The { open brace starts a group of code (code block) that will be made accessible because of the extern keyword.
  5. #endif is a command used by the C preprocessor that means “End if”.  It is used here to end the #ifdef statement from line 3.  Every #if statement requires a matching #endif
  6. // is a single line comment.  Almost all C compilers support this.  If you want to be extra careful that your code will be portable (supported by ALL C compilers), you should write all comments like this instead:
    /* public header code goes here */
  7. #ifdef is here again to ensure we only write the code below it if this is a C++ compiler
  8. } is a closed brace that ends the extern group started at line 4
  9. #endif ends the #ifdef at line 7
  10. #endif ends the #ifndef at line 1.  The single line comment // to the side of the #endif makes it easy to find the #if statement that is being ended here.  This is because there could be hundreds of lines of code between the #if and #endif so it is not easy to read without the extra comment.
  11. This line should be empty.  This webpage won’t let me show it, but this should be an empty line.  If the last line in your file is not empty, the preprocessor could accidentally put code right next to it without any indication that it should have been separate.  If any of your .h or .c files do not have an empty line at the end, go add them now.

Step 3

Create a text file for the private header that ends with .h to indicate it is a header file.  Save this file in your include directory.  For example, the path to my file is:

organized/include/organized_private.h

Paste the header template code into your file and change the #define name and the comment to indicate this is your private header.  For example, I have changed lines 1,2,6,and 10:

#ifndef ORGANIZED_PRIVATE_H
#define ORGANIZED_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
// private&amp;amp;amp;nbsp;header code goes here
#ifdef __cplusplus
}
#endif
#endif // ORGANIZED_PRIVATE_H
// empty line

That is it for Part 1.  You can download the sample code here.

In the next part we will start to fill-in the public header file.