How to Search a file in QDir - macos

I am developing an Application for MAC OS X. In which I have to find files in folder. Problem is that I want to give comfort, to user, to search a file by entering a QString. This QString may be the exact name of file or a text contain in the file name.Suppose the file name is "mysamplefile.txt". So if user enter either 'my' ; 'mysample' ; 'samplefile' ; 'mysamplefile' or 'mysamplefile.txt'. In all cases I want to get the QFileInfo for that file. I also give checkbox option 'Match Case' or 'Ignore case' to the user to get fileinfo. I have a QStringList for the strings that user want to search and I also have a QStringList of the locations selected by the user. So I want to search each string name(from QStringList strSearchFileName) in every Path(QStringList searchingdirectorylist). And I want to make a final QFileInfoList for all files after the searching process.
void MainWindowWipe::onSearchingProcess(QStringList strSearchFileName, QStringList searchingdirectorylist)
{
for(int i=0; i<strSearchFileName.size();i++)
{
for(j=0; j<searchingdirectorylist.size();j++)
{
QDir dir(searchingdirectorylist[j]);
dir.setNameFilters(QStringList(strSearchFileName[i]));
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QFileInfoList fileList = dir.entryInfoList();
for (int k=0; k<fileList.count(); k++)
{
QString temp = "";
temp = fileList[k].absoluteFilePath();
}
dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QStringList dirList = dir.entryList();
QStringList newList;
for (int l=0; l<dirList.size(); ++l)
{
QString newPath = QString("%1/%2").arg(dir.absolutePath()).arg(dirList.at(i));
newList<<newPath;
onSearchingProcess(strSearchFileName,newList);
}
}
}
}
This function is not working for me this work only when if I search only one file with exact name. But I want to search multiple files with not exact name.

You need to iterate through all the files and folders using a recursive function (or use the iterator). On each iteration you can use the QString::contains() to find out if the file's name contains the target string. Save each matching file name in a list.
#include <QCoreApplication>
#include <QDebug>
#include <QDirIterator>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString targetStr = "init"; // What we search for
QFileInfoList hitList; // Container for matches
QString directory = "D:/python/"; // Where to search
QDirIterator it(directory, QDirIterator::Subdirectories);
// Iterate through the directory using the QDirIterator
while (it.hasNext()) {
QString filename = it.next();
QFileInfo file(filename);
if (file.isDir()) { // Check if it's a dir
continue;
}
// If the filename contains target string - put it in the hitlist
if (file.fileName().contains(targetStr, Qt::CaseInsensitive)) {
hitList.append(file);
}
}
foreach (QFileInfo hit, hitList) {
qDebug() << hit.absoluteFilePath();
}
return a.exec();
}

Related

How to properly compare Q_ENUM and QStringList

I have a small example .ui where the user can drag and drop from a QListWidget to a QGraphicsView using QGraphicsProxyWidget a specific widget (in my case is a QTableWidget) as shown below.
Basically the behavior I have been looking for is:
If I drag and drop "Imgaes" than the QTableWidget on the QGraphicsView will have 2 columns and 2 rows; (which is correct)
If I drag and drop "Path" than the QTableWidget on the QGraphicsView will have 3 columns and 3 rows; (which is wrong)
[1] : https://imgur.com/NQ1DZpx
Below the selection of "Path", which still give 2 rows and 2 columns instead of 3 rows and 3 columns
[2] : https://imgur.com/d4YcOiL
Below the code:
scene.h
class Scene : public QGraphicsScene {
enum LaserTableWidget {
Images,
Path
};
Q_ENUM(LaserTableWidget)
public:
Scene(QObject *parent = nullptr);
void compare(const QString& comp);
template<typename QEnum>
std::string QtEnumToString (const QEnum value)
{
return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
}
protected:
void dropEvent(QGraphicsSceneDragDropEvent *event);
scene.cpp
Scene::Scene(QObject *parent) : QGraphicsScene(parent) {
setBackgroundBrush(Qt::lightGray);
}
void Scene::compare(const QString &comp)
{
// get information about the enum named "LaserTableWidget"
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("LaserTableWidget"));
QStringList tabs;
switch (MetaEnum.keyToValue(comp.toUpper().toLatin1()))
// or simply switch (MetaEnum.keyToValue(word)) if no string modification is needed
{
case Images:
for (const QString &color : tabs) {
QPoint initPos(0,0);
QTableWidget *wgt = new QTableWidget;
QGraphicsRectItem *proxyControl = addRect(initPos.x(), initPos.y(), wgt->width(), 20, QPen(Qt::black), QBrush(Qt::darkGreen)); // widget->width() works properly here because of the resize(layout->sizeHint()) that we have used inside it
proxyControl->setFlag(QGraphicsItem::ItemIsMovable, true);
proxyControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
wgt->setColumnCount(2);
wgt->setRowCount(2);
for (int ridx = 0 ; ridx < wgt->rowCount() ; ridx++ )
{
for (int cidx = 0 ; cidx < wgt->columnCount() ; cidx++)
{
QTableWidgetItem* item = new QTableWidgetItem();
item->setText(QString("%1").arg(ridx));
wgt->setItem(ridx,cidx,item);
}
}
QGraphicsProxyWidget * const proxy = addWidget(wgt);
// In my case the rectangular graphics item is supposed to be above my widget so the position of the widget is shifted along the Y axis based on the height of the rectangle of that graphics item
proxy->setPos(initPos.x(), initPos.y()+proxyControl->rect().height());
proxy->setParentItem(proxyControl);
}
break;
case Path:
for (const QString &color : tabs) {
QPoint initPos(0,0);
QTableWidget *wgt = new QTableWidget;
QGraphicsRectItem *proxyControl = addRect(initPos.x(), initPos.y(), wgt->width(), 20, QPen(Qt::black), QBrush(Qt::darkGreen)); // widget->width() works properly here because of the resize(layout->sizeHint()) that we have used inside it
proxyControl->setFlag(QGraphicsItem::ItemIsMovable, true);
proxyControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
wgt->setColumnCount(3);
wgt->setRowCount(3);
for (int ridx = 0 ; ridx < wgt->rowCount() ; ridx++ )
{
for (int cidx = 0 ; cidx < wgt->columnCount() ; cidx++)
{
QTableWidgetItem* item = new QTableWidgetItem();
item->setText(QString("%1").arg(ridx));
wgt->setItem(ridx,cidx,item);
}
}
QGraphicsProxyWidget * const proxy = addWidget(wgt);
// In my case the rectangular graphics item is supposed to be above my widget so the position of the widget is shifted along the Y axis based on the height of the rectangle of that graphics item
proxy->setPos(initPos.x(), initPos.y()+proxyControl->rect().height());
proxy->setParentItem(proxyControl);
}
break;
default:
break;
}
}
void Scene::dropEvent(QGraphicsSceneDragDropEvent *event) {
QByteArray encoded =
event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
QStringList rosTables;
while (!stream.atEnd()) {
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
rosTables << roleDataMap[Qt::DisplayRole].toString();
}
compare(const QString &comp)
}
I tried to use the template function declared on the header file that for completeness I am also attaching below:
template<typename QEnum>
std::string QtEnumToString (const QEnum value)
{
return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
}
Maybe I the template function is the wrong choice? I was trying to find a way to use it if possible.
That is the reason why I switched to a void compare(const QString& comp); function and tried to delegate the job to a switch - case statement but that also is not working as I expect and I still see the same exact QtableWidget dropped onto the QGraphicsView.
Of course I did more research and came across this source and above all this post which was useful to understand the basic comparison and following this post I decided to go ahead and try to apply the Q_ENUM - QString or even the QStringList as a valuable tool. But I could not figure out what I was doing wrong.
Can anyone please shed light on which approach could be better? (or maybe they are both correct) and try to explain what I am missing to solve this problem.
There are two problems I see in your code:
Wrong parameter passed to keyToValue(). Since you have Image and Path in your enum, the valid values to pass to keyToValue() are "Image" (returns 0), and "Path" (return 1), other values will returns -1.
In the function Scene::compare(), tabs is just created as an empty QStringList, so the code inside the loops for (const QString &color : tabs) are never executed
Below is a test program to show you what I mean:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMetaEnum>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum LaserTableWidget
{
Images,
Path
};
Q_ENUM(LaserTableWidget)
template<typename enum_type>
QString QtEnumToString (const enum_type value)
{
return QMetaEnum::fromType<enum_type>().valueToKey(value);
}
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QDebug>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// First problem: wrong parameter passed to keyToValue()
qDebug() << 1 << QtEnumToString<LaserTableWidget>(Images);
qDebug() << 2 << QtEnumToString<LaserTableWidget>(Path);
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("LaserTableWidget"));
qDebug() << 3 << MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toUpper().toLatin1());
qDebug() << 4 << MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toStdString().c_str());
switch (MetaEnum.keyToValue(QtEnumToString<LaserTableWidget>(Path).toUpper().toLatin1()))
{
case Images:
qDebug() << "switch Images";
break;
case Path:
qDebug() << "switch Path";
break;
default:
qDebug() << "switch default";
break;
}
// Second problem: tabs is empty
QStringList tabs;
for (const QString &color : tabs)
qDebug() << color; // this line is never executed
}
MainWindow::~MainWindow()
{
}
Output:
1 "Images"
2 "Path"
3 -1
4 1
switch default

STL binary_search()

I created a struct directory with data members as string name and address and phone no.s. I want to perform binary search using STL c++ binary_search() to display info by taking input as name. And my structure is array of structs. I have successfully sorted the structure by name. How do I search and display? I am not getting the syntax.
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
using namespace std;
struct directory
{
string name;
char address[50];
long long int ph;
int pin;
}d[10];
bool compare(directory & lhs, directory & rhs)
{
if(lhs.name!=rhs.name)
{
return lhs.name < rhs.name;
}
}
int main()
{
for(int i=0;i<10;i++)
{
cout<<"\nEnter name: ";
cin>>d[i].name;
cout<<"\nEnter Address:";
cin.ignore();
cin.getline(d[i].address,50);
cout<<"\nEnter ph. no.: ";
cin>>d[i].ph;
}
sort(d,d+10,&compare);
for(int i=0;i<10;i++)
{
cout<<"\nName: "<<d[i].name;
cout<<"\nAddress:"<<d[i].address;
cout<<"\nPh. no.: "<<d[i].ph<<"\n";
}
string nam;
cout<<"Enter the first name to search: ";
cin>>nam;
if(binary_search(d,d+10,nam,&compare));
{
cout<<d->name<<"\n";
cout<<d->address<<"\n";
cout<<d->ph<<"\n";
}
return 0;
}

A more convenient way to see project dependencies?

VS has the "Project Dependencies" window but in a solution I work on there are over 100 projects. Trying to see all the dependencies of a specific project is time-consuming as you have to scroll through the entire list, and it's easy to miss one.
Is there a way just to list the dependencies, not all the projects with a tick-box showing which are dependencies?
You may open a Visual Studio Solution file (.sln) in a text editor, for example, Notepad++. Once opened, search for ProjectSection(ProjectDependencies) = postProject within the specific project you are looking for.
The example of part of a .sln file below shows that the NativeUnitTest_CppDll project depends on NativeWin32CppDll project.
The only downside is that the dependencies are listed as GUIDs. You will have to do a text Find to locate their project names.
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NativeWin32CppDll", "NativeWin32CppDll\NativeWin32CppDll.vcxproj", "{83FC3109-17DF-4B53-BCA0-F0DFC10AAE7F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NativeUnitTest_CppDll", "NativeUnitTest_CppDll\NativeUnitTest_CppDll.vcxproj", "{559CB21A-4763-4A1E-A70A-E8C656C53ED9}"
ProjectSection(ProjectDependencies) = postProject
{83FC3109-17DF-4B53-BCA0-F0DFC10AAE7F} = {83FC3109-17DF-4B53-BCA0-F0DFC10AAE7F}
EndProjectSection
EndProject
Could you please clarify: to see and list where? In the Visual Studio or some external tool? Just to see in a pop-up or to have an ability to copy the list?
I was trying to get those dependencies using Visual Studio's Solution object and its properties. There is a property named ProjectDependencies, but it was empty on my test, so I assume it is tracking auto-dependencies, not the one you specify manually.
Then I tried to get the list out of *.sln file, as was also suggested by gxy, in a simple console project (you should pass the solution file on a command line):
int main(int argc, char* argv[])
{
if (argc != 2)
return -1;
ifstream sln(argv[1]);
string line, name, guid;
unordered_map<string, string> names;
unordered_map<string, list<string>> dependencies;
while (getline(sln, line))
{
if (line.find("Project(") == 0)
{
ParseProjGuid(line, name, guid);
names[guid] = name;
while (getline(sln, line))
{
if (line == "EndProject")
break;
if (line.find("ProjectSection(ProjectDependencies)") != string::npos)
{
while (getline(sln, line))
{
if (line.find("EndProjectSection") != string::npos)
break;
ParseDependGuid(line, guid);
dependencies[name].push_back(guid);
}
}
}
}
}
for (auto d : dependencies)
{
cout << d.first << endl;
for (auto g : d.second)
cout << "\t" << names[g] << endl;
}
return 0;
}
I am using a couple of helper functions there:
string unquote(const string& s)
{
if (s[0] == '"' && s[s.length() - 1] == '"')
return s.substr(1, s.length() - 2);
else
return s;
}
void ParseProjGuid(const string& src, string& proj, string& guid)
{
// Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "name", "path\name.vcxproj", "{9D4B97C3-1069-406C-973F-652706414C86}"
size_t pos1 = src.find('=');
size_t pos2 = src.find(',');
size_t pos3 = src.rfind(',');
proj = src.substr(pos1 + 1, pos2 - pos1 - 1);
guid = src.substr(pos3 + 1);
proj = trim(proj);
guid = trim(guid);
proj = unquote(proj);
guid = unquote(guid);
}
void ParseDependGuid(const string& src, string& guid)
{
// {165C1503-36B1-4577-9D99-3C1AFEBFC201} = {165C1503-36B1-4577-9D99-3C1AFEBFC201}
size_t pos = src.find('=');
guid = src.substr(0, pos);
guid = trim(guid);
}
As well as trim function borrowed from from What's the best way to trim std::string?:
// trim from start
static inline string &ltrim(string &s) {
s.erase(s.begin(), find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
static inline string &rtrim(string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
static inline string &trim(string &s) {
return ltrim(rtrim(s));
}
As my hobby is writing Visual Studio extensions, I have a question: do you think it will be a useful tool?

Reading encrypted text in program in c++

I need some help to decrypt my text file and make it able to read in my program..
What I have programmed so far is to read the encrypted file, create a new file, decrypt it and read the newly created file..
I need to decrypt the encrypted file without having to create a new file that reads the decrypted text..
Well, Let me show you my code:
P.S Most of the include is not needed and I already know that
Visual studio 2010 Windows Form Application CLR
#pragma once
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <iomanip>
namespace EncryptandDecryptfiletest {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
using namespace std;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
/*Decryption --- When program loads*/
char ch,mod;
char key = 97;
char name[100] = "Encrypted.txt";
char target[100] = "TTO.txt";
ifstream fin("Encrypted.txt", ios::binary); // Reading file
if(!fin) //open the encrypted file in a binary mode
{
MessageBox::Show("Encrypted.txt did not open"); //If file does not exist
} //or any kind of error
ofstream fout;
fout.open(target,ios::binary); //Opens outputfile
if(!fout)
{ //Show error if any error occurs in opening new file
MessageBox::Show("TTO.txt did not open");
}
while(fin.get(ch))
{ // opens the Encrypted file
if(ch==EOF)break;
mod = ch + key;
if (mod > 255 ) mod -= 255;
fout << mod; //Writes decrypted text to TTO.txt
}
fin.close(); //Close the encrypted file
fout.close(); // Close the decrypted file
}
private: System::Void comboBox1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
label1->Text = comboBox1->Text;
pictureBox1->Load("Images\\" + comboBox1->SelectedItem->ToString() + ".png");
//String^ openFileTest = "Encrypted.txt"; // Opens the encrypted .txt file
String^ openFileTest = "TTO.txt"; //Opens the newly created file that is decrypted
try //Reading the .txt file
{
StreamReader^ DataIn = File::OpenText(openFileTest);
String^ DataStr;
int count = 0;
array<String^>^ result;
array<Char>^ separ = gcnew array<Char>{'"'}; //After each Quote gets a new value of result[x]
while((DataStr = DataIn->ReadLine()) != nullptr)
{
count++;
result = DataStr->Split(separ);
if(comboBox1->Text == result[0]) // result[0] = Name
{
textBox1->Text = result[1]; //reads first word in txt file
textBox2->Text = result[2]; //second word in txt file
textBox3->Text = result[3]; //third word in txt file
}
} // ends while()
} // ends try
catch (Exception^ e)
{
if(dynamic_cast<FileNotFoundException^>(e))
MessageBox::Show("File " + openFileTest + " not found");
}
} // Ends comboBox1_SelectedIndexChanged void
};
}
You have my decryption code and the code I want to use..
I have uploaded the code for you to use on your computer because it is fairly hard for me to explain..
I want to be able to read the encrypted file in my program, without having to writing a new file to decrypt it..
I hope anyone is able to help me
Decrypted & Encrypted .txt file Included (And images)
--> Program .rar pack link <--
Build it with Visual Studio 2010
Just replace the output file stream with a MemoryStream.
The first thing to do is decompose into functions. Since you read your streams byte per byte, you won't need readers, which is good.
void Decrypt(Stream^ input, Stream^ output)
{
char key=97;
int byteRead;
while((byteRead=input->ReadByte()) >= 0)
{
char ch = (char)byteRead;
char mod = (char)(ch+key)
output->WriteByte(mod);
}
}
//When loading
MemoryStream^ ms = gcnew MemoryStream();
{
FileStream^ fs = File::OpenRead(L"encrypted.txt");
Decrypt(fr, ms);
delete fs;
}
ms.Seek(0, SeekOrigin::Begin);
//Later, read from the memory stream

How can we check if a file Exists or not using Win32 program?

How can we check if a file Exists or not using a Win32 program? I am working for a Windows Mobile App.
Use GetFileAttributes to check that the file system object exists and that it is not a directory.
BOOL FileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
Copied from How do you check if a directory exists on Windows in C?
You can make use of the function GetFileAttributes. It returns 0xFFFFFFFF if the file does not exist.
You can call FindFirstFile.
Here is a sample I just knocked up:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int fileExists(TCHAR * file)
{
WIN32_FIND_DATA FindFileData;
HANDLE handle = FindFirstFile(file, &FindFileData) ;
int found = handle != INVALID_HANDLE_VALUE;
if(found)
{
//FindClose(&handle); this will crash
FindClose(handle);
}
return found;
}
void _tmain(int argc, TCHAR *argv[])
{
if( argc != 2 )
{
_tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
return;
}
_tprintf (TEXT("Looking for file is %s\n"), argv[1]);
if (fileExists(argv[1]))
{
_tprintf (TEXT("File %s exists\n"), argv[1]);
}
else
{
_tprintf (TEXT("File %s doesn't exist\n"), argv[1]);
}
}
How about simply:
#include <io.h>
if(_access(path, 0) == 0)
... // file exists
Another option: 'PathFileExists'.
But I'd probably go with GetFileAttributes.
Came across the same issue and found this brief code in another forum which uses GetFileAttributes Approach
DWORD dwAttr = GetFileAttributes(szPath);
if (dwAttr == 0xffffffff){
DWORD dwError = GetLastError();
if (dwError == ERROR_FILE_NOT_FOUND)
{
// file not found
}
else if (dwError == ERROR_PATH_NOT_FOUND)
{
// path not found
}
else if (dwError == ERROR_ACCESS_DENIED)
{
// file or directory exists, but access is denied
}
else
{
// some other error has occured
}
}else{
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
{
// this is a directory
}
else
{
// this is an ordinary file
}
}
where szPath is the file-path.
You can try to open the file. If it failed, it means not exist in most time.
Use OpenFile with uStyle = OF_EXIST
if (OpenFile(path, NULL, OF_EXIST) == HFILE_ERROR)
{
// file not found
}
// file exists, but is not open
Remember, when using OF_EXIST, the file is not open after OpenFile succeeds. Per Win32 documentation:
Value
Meaning
OF_EXIST (0x00004000)
Opens a file and then closes it. Use this to test for the existence of a file.
See doc:
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfile
Another more generic non-windows way:
static bool FileExists(const char *path)
{
FILE *fp;
fpos_t fsize = 0;
if ( !fopen_s(&fp, path, "r") )
{
fseek(fp, 0, SEEK_END);
fgetpos(fp, &fsize);
fclose(fp);
}
return fsize > 0;
}

Resources