Visual Studio's 'Format document' doesn't recognize Q_FOREACH macro - visual-studio

I've noticed that Qt's Q_FOREACH macro doesn't play well with certain features of Visual Studio:
IntelliSense detects it as a function declaration: every Q_FOREACH is displayed as a function/method in the class viewer. Fortunately this answer solves that problem.
Code formatting also detects it as a function declaration (Edit > Advanced > Format Document). For example, for my current format style:
void foo() {
Q_FOREACH (auto action, actions){ (action);
}
for (int i = 0; i < 10; ++i) { (i);
}
}
is formatted as
void foo()
{
Q_FOREACH(auto action, actions)
{
(action);
}
for (int i = 0; i < 10; ++i) {
(i);
}
}
instead of
void foo()
{
Q_FOREACH (auto action, actions) {
(action);
}
for (int i = 0; i < 10; ++i) {
(i);
}
}
Is there any way to fix it? The cpp.hint hint used to solve the first problem related to IntelliSense is already applied and hasn't helped with the format.
PS: I'm working with Visual Studio Professional 2017 and using Visual Studio Add-in 2.1.1 for 2017 (beta 10.03.2017, downloaded from https://download.qt.io/development_releases/vsaddin/).
Update: To give some additional context, we've just started the migration from VS 2010 to VS 2017. Currently we've only migrated the IDE, toolsets are still on 2010, where the natural replacement, the C++11 range-for, is not available for that version of the C++ compiler.
Up to know, some of the members of the team have been using AStyle (and its VS plugin) for code formatting, which deals with this situation (and other Qt related things) in a more or less acceptable fashion. I began to study the possibility of migrating to the native code formatter and found this, that's why I posted this question.
Related questions that haven't solved my problem:
Broken indentation for Qt-specific constructions in Visual Studio

Yes. The fix is very simple: don't use that macro. It's unnecessary. Use range-for instead. You want to write:
void foo()
{
for (auto action : actions)
action->doSomething();
}

Related

How to check return value of function in Visual Studio?

If I step through a code in debugging and for something like below how to easily check the return value of the function?
for (i = 0; i < Count(); ++i)
I want to see the value of "Count()".
In the Autos window Visual Studio automatically shows the returned value:

Is there a way to comment selected lines instead of the selected range of text in Visual studio?

If I try to comment out several lines in Visual Studio I typically get this result:
int f/*oo = 1;
float bar = doSo*/mething(foo);
But what I want to happen is:
// int foo = 1;
// float bar = doSomething(foo);
Every other IDE/text editor that I'm used to produces the second result.
This Visual Studio extension does the trick

qtcreator does not autocomplete when structure bindings is used?

I seem to have an issue with qtcreator not autocompleting my code, which is getting pretty annoying.
Currently is it not able to autocomplete when i try to use structure bindings in for loops like this..
std::vector<pair<string,AudioFile<double>>> list_of_files;
// Some init of list_of_file
for (const auto& [name,file]: this->list_of_files) // red line under this.. does seem to like structure bindings?
{
file.printSummary(); // qtcreator don't offer any autocomplete options?
}
qtcreator basically complains about everything about the code posted above..
But when I write it like this:
for (int i = 0 ; i <list_of_file.size() ; i++) // No red lines under this..
{
list_of_files[i].second.printSummary() // Autocompletes without any problems.
}
qtcreator does not complain about this code, and seem to autocomplete it just fine.. So why is it causing so many problems with c++17 style?
Any fixes for this?
A temporary solution for this seem to be something like this - which autocompletions does not complain about, and seem to suit my definition of (readability):
for ( const auto &elements : this->list_of_files)
{
auto name = std::get<0>(elements);
auto file = std::get<1>(elements);
}

Getting list of system printer names very slow in windows

I need to create a very custom widget for printing. It has to be multi-platform as well. For consistency, the widget should be similar looking in windows as in linux or mac... After studying the Qt code, which uses the Windows print dialog, I gave up trying to subclass Qt print dialog, and made my own widget.
So, now I am on step 1: populate the list of printers on the system. I added the following code, to be called on each "show()" - just in case printers on the system change during program execution - and it works, but it is extremely slow:
I create a map of index/printer, and add the default printer as index -1, to tell the widget which one it is.
QMap<int, QString> PrintController::getListOfSystemPrinters()
{
QMap<int, QString> printerNames;
#ifdef Q_OS_WIN32
#ifdef NOT_QT_4 // I tried to use "availablePrinterNames" thinking it will be faster but it actually seems slower
QPrinter currentPrinter;
QString printerName = currentPrinter.printerName();
QStringList printerNameList = QPrinterInfo::availablePrinterNames();
int index = 0;
foreach(QString printerName1, printerNameList)
{
printerNames.insert(index, printerName1);
if(printerName == printerName1)
printerNames.insert(-1, printerName1);
++index;
}
#else
QPrinter currentPrinter;
QString printerName = currentPrinter.printerName();
QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
int index = 0;
foreach(QPrinterInfo printerInfo, printers)
{
QString printerName1 = printerInfo.printerName();
printerNames.insert(index, printerName1);
if(printerName == printerName1)
printerNames.insert(-1, printerName1);
++index;
}
#endif
#elif defined Q_OS_UNIX
#endif
return printerNames;
}
This is the slowest piece of code I have ! I don't see another way to get all printer names... But I must be doing something wrong !
The Qt 5 version is slightly slower than the Qt 4 version... Either way, they are both slow....
The call to create a QPrinterInfo is slow.
So... are there alternatives ?
How can I get the list of printer names in Windows ?
Note this must work in Qt 4.7-5.x
Get printer list asynchronously:
class Class : public QObject {
Q_OBJECT
Q_SIGNAL void hasPrinters(const QList<QPrinterInfo> &);
Q_SIGNAL void hasPrinterNames(const QStringList &);
/// This method is thread-safe
void getPrinters() {
#if QT_VERSION >= QT_VERSION_CHECK(5,3,0)
emit hasPrinterNames(QPrinterInfo::availablePrinterNames());
#else
emit hasPrinters(QPrinterInfo::availablePrinters());
#endif
}
void test() {
QtConcurrent::run(this, &Class::getPrinters);
}
};
The above compiles on Qt 4.7 & up, using either C++98 or C++11.
Connect to the hasPrinterNames/hasPrinters signal to be notified when the printer list is available, then populate your dialog.
You might be lucky and availablePrinterNames/availablePrinters will be thread-safe. I haven't checked if it is.
On Qt 5.3 and newer, only create the QPrinterInfo for a given printer once your user has selected it, and you might want to create it concurrently as well.

Make Visual Studio's 'Smart Indent' use my coding style

I own Visual Studio 2015 Enterprise and I'm unsure about making VS' Smart Indent feature use my coding style, so far I've configured most of it, except for ternary operators. Example:
bool bSomeBoolean = true;
// my code
for(int i = 1; i <= 39; i++)
{
Console.WriteLine(bSomeBoolean? "Yes":"No");
}
// smart indent
for(int i = 1; i <= 39; i++)
{
Console.WriteLine(bSomeBoolean ? "Yes" : "No");
}
VS will add the space before the question mark, also before and after the colon.
How could I stop it from happening? Couldn't find anything in the settings.
Thanks!
Although the smart indent provides beautification to code and improves readability. But if you anyhow don't want this feature, you can turn off the reformatting of code (pretty listing)
In VS2015, you can find this setting at-
Tools > Options > Text Editor > Basic > Advanced > Pretty Listing (uncheck this)
Hope this helps!

Resources