Search code examples
c++stringtooltipc-preprocessormingw32

Are there more effective or efficient ways to code lengthy texts?


I have an application that will have numerous lengthy tooltips. For example I have code, for just one such tooltip, along the lines of the following:-

//Less SSA (ATi-SSA) (as coded in a header)
std::string GetLessSSA_tt() {
    std::string less_ssastr = "Less SSA = The amount after deducting the SSA from the ATI.";
    less_ssastr.append("\n\nAs such reducing the amount used for calculation purposes");
    //etc
    return less_ssastr;
}

 ......

//Coded at various places not within the header
std::string tooltip = GetLessSSA_tt();

I believe that a header file is perhaps the most apt place for separation of data and code, and to avoid duplication of data.

I'm open to suggestions of where to place the data (I'd rule out file/database though due to the requirement for more coding and having the data, which would rarely need updating, distant and perhaps prone to misuse e.g. a file could be changed).

The real issue is the actual coding for the storage of the text. There will be quite a considerable amount. The above example is a simplified/minimalist example of one of the smaller texts. There will be at least 27 topics (terms explained), which equates using, the example methodology, to 27 functions, each likely have at least 5 lines of text.

Arrays/deques/structures would all, I guess, increase duplication.

My knowledge of and ability to use pre-processor commands/macros is currently very limited. All my attempts to use '#defines' failed.

I believe, perhaps mistakenly, that pre-processor commands, could limit portability (not really an issue). However, I suspect that perhaps the pre-processor could make for more efficient/effective coding.

A summary of what I am trying to achieve is

"to reduce the clutter around the text strings to a minimum. Primarily their definition but also considering subsequent usage."


Solution

  • I would place it in a single C++ file, should work with simple constants:

    tooltip.h:

    namespace Whatever
    {
    extern std::string const ToolTip1;
    extern std::string const ToolTip2;
    }
    

    tooltip.cpp:

    namespace Whatever
    {
    std::string const ToolTip1(
            "some lengthy tooltip\n"
            "with several lines"
            );
    std::string const ToolTip2(
            "a shorter one"
            );
    }
    

    If you prefer functions:

    tooltip.h:

    namespace Whatever
    {
    std::string const& toolTip1();
    std::string const& toolTip2();
    }
    

    tooltip.cpp:

    namespace Whatever
    {
    namespace
    {
    std::string const ToolTip1(
            "some lengthy tooltip\n"
            "with several lines"
            );
    std::string const ToolTip2(
            "a shorter one"
            );
    }
    
    std::string const& toolTip1() { return ToolTip1; }
    std::string const& toolTip2() { return ToolTip2; }
    }
    

    I would not place the constants into a header - you at first multiply the constants in the single compilation units, and I feel uncomfortable relying on the linker spotting identical strings...

    Edit: Considering MikeT's comments and (rejected) edit:

    tooltip.h:

    namespace Whatever
    {
    extern char const* const ToolTip1;
    extern char const* const ToolTip2;
    }
    

    tooltip.cpp:

    namespace Whatever
    {
    char const* const ToolTip1 = "theToolTip";
    char const* const ToolTip2 = "theToolTip";
    }
    

    Usage:

    // before:
    // addToolTip(getToolTip1().c_str());
    // now:
    addToolTip(ToolTip1);
    

    As long as there is only one single include of the header file globally (into one single source file, and not included within other headers), there won't be a problem moving the definitions from the tooltip.cpp file into the header file and drop the source file. I consider this insecure, though, as this might lead to linker problems as soon as this fact changes. Keeping header and source file separate as I proposed will prevent problems now and in the future.

    Additionally, it makes exchanging the language at compile time easy, as we can simply do:

    gcc main.cpp, something.cpp, tooltip_en-GB.cpp -o theApplication # English translation
    gcc main.cpp, something.cpp, tooltip_es-ES.cpp -o theApplication # Spanish translation
    # ...