Open function in Qt - c++

I have been creating an application in qt. I have added open function in it, but was happening that when I open an already open file, it again opens the same file instead of pointing it to already opened file.
void MainWindow::actionOpen()
{
QFileInfo fileInfo = UIUtils::openFile(this);
if (!fileInfo.exists()) {
return;
}
if (!MainWindow::mdiMode && !maybeSave()) {
return;
}
openFile(fileInfo.filePath());
}
Please help me to solve the problem.

I'm not 100 % clear on what the issue is, but if you don't want to run the openFile function on files you've previously opened, you have to keep a record.
For instance, define a QList in your header file:
QList<QFileInfo> knownFiles;
And then keep it up to date and check it:
void MainWindow::actionOpen()
{
QFileInfo fileInfo = UIUtils::openFile(this);
if (!fileInfo.exists()) {
return;
}
if (!MainWindow::mdiMode && !maybeSave()) {
return;
}
bool fileIsKnown = false;
for(qint64 i=0; i<knownFiles.length(); i++)
if(knownFiles.at(i) == fileInfo)
{
fileIsKnown = true;
break;
}
if(!fileIsKnown)
{
knownFiles << fileInfo;
openFile(fileInfo.filePath());
}
}
I don't know what you mean when you say "instead of pointing it to already opened file.".

Related

Zip directory recursion

I am working on creating zip archive using old Qt - ZipWriter class. The problem is when I want to add the directory. The default Qt code for addDirectory method - d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());. It does not add any content, only the empty directory. So, I have improved it to add the directories and content as well.
My code:
QList<QString> dirs;
int recursion = 0;
void ZipWriter::addDirectory(const QString &dirPath)
{
QDir archDir(dirPath);
archDir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
dirs << addDirSeparator(archDir.dirName());
if (archDir.exists()) {
QString archDirName = "";
if (recursion > 0) {
for (int i = recursion; i < dirs.count(); i++) {
archDirName = dirs.first().append(dirs.at(i));
}
} else {
archDirName = dirs.at(recursion);
}
if (!archDir.isEmpty()) {
const QStringList archFileList = archDir.entryList();
if (archFileList.count() > 0) {
for (QString archFile : archFileList) {
QFileInfo archFileInfo(QDir::toNativeSeparators(QString("%1/%2").arg(archDir.absolutePath(), archFile)));
if (archFileInfo.isDir()) {
recursion++;
addDirectory(archFileInfo.absoluteFilePath());
} else {
QFile zipFile(archFileInfo.absoluteFilePath());
zipFile.open(QIODevice::ReadOnly);
addFile(QString("%1%2").arg(archDirName, archFile), zipFile.readAll());
zipFile.close();
}
}
}
} else {
d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());
}
}
}
Now, it adds the directory and content recursively but it has issue when directory is on the same level, it appends it to the end. I think, I must use the STL container to keep track of the directory for example QMap but the question is how to get the current directory level? Any ideas? Thank you.
Updated: 01.05.2022
I have change my code to this:
void ZipWriter::addDirectory(const QString &dirPath)
{
QDirIterator dirIt(dirPath, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (dirIt.hasNext()) {
QString archDirPath = dirIt.next();
QFile zipFile(archDirPath);
zipFile.open(QIODevice::ReadOnly);
if (!dirIt.fileInfo().isDir()) {
addFile(archDirPath, zipFile.readAll());
}
zipFile.close();
}
}
It adds everything recursively and in correct order but I have another issue. Now, it adds the full path to the archive. For example, I want to add this folder and it's content to the archive: 22610.1_amd64_en-us_professional_00fb7ba0_convert.
In the archive I get: C:\Users\userProfile\Downloads\22610.1_amd64_en-us_professional_00fb7ba0_convert. Any ideas how to make this relative path or trim it? Thank you.
You can use QDirIterator to recursively iterate over directory and subdirectories, and I believe you dont need to add nonempty directories at all, just files will be fine.
And why would you use stl container in qt, please use qt containers.

Download multiple files from Ftp issue

I want to download some files from my ftp server. The problem is, that only the last one has data, others 0 sized or it crashes when close QFile as a pointer.
My code:
QFtp *ftp = new QFtp(this);
ftp->connectToHost(FTP_HOST, FTP_PORT);
ftp->login(FTP_USERNAME, FTP_PASSWORD);
QFile *reportFile = nullptr;
connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) {
if (ftpUrlInfo.isFile()) {
reportFile = new QFile("some local path" + ftpUrlInfo.name());
reportFile->open(QIODevice::WriteOnly);
ftp->get("some ftp path" + ftpUrlInfo.name(), reportFile, QFtp::Binary);
}
});
connect(ftp, &QFtp::done, [this]() {
qDebug() << "DONE!";
ftp->close();
ftp->deleteLater();
});
connect(ftp, &QFtp::commandFinished, [this]() {
qDebug() << "COMMAND FINISHED!";
if (reportFile != nullptr) {
reportFile.close();
reportFile->deleteLater();
}
});
ftp->list("ftp path to dir");
So, it should download the file, close it and deleteLater for all files in the ftp directory. Any ideas how to do it? Thanks.
I have finally fixed it!
My code:
QQueue<QFile*> reportQueue; //initialize the queue
connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) {
if (ftpUrlInfo.isFile()) {
reportQueue.append(new QFile("local path" + "\\" + ftpUrlInfo.name()));
}
});
connect(ftp, &QFtp::done, [this]() {
emit reportsDataFinished();
});
connect(ftp, &QFtp::commandFinished, [this]() {
if (ftp->currentCommand() == QFtp::List) {
proceedDownload();
} else if (ftp->currentCommand() == QFtp::Get) {
reportFile->close();
reportFile->deleteLater();
proceedDownload();
}
});
if (ftp->error() == QFtp::NotConnected) {
emit ftpReportError(ftp->error());
} else {
ftp->list("ftp path to the dir");
}
void Test::proceedDownload()
{
if (!reportQueue.isEmpty()) {
reportFile = reportQueue.dequeue();
reportFile->open(QIODevice::WriteOnly);
QFileInfo ftpFileInfo(reportFile->fileName());
ftp->get("ftp path to file" + "/" + ftpFileInfo.fileName(), reportFile, QFtp::Binary);
}
}
I added the files to the QQueue, when ftp list command has been finished, I use function proceedDownload(). In the function, I dequeue() the queue to the reportFile and proceed with ftp get() function. When get ftp command finishes, I close and delete the file from memory, and again call the proceedDownload(). So the the whole process goes again until the queue is empty. I use emit reportsDataFinished(); signal in the connection to the slot closeFtp() where ftp closes and deleteLater() frees the resources. All files downloads well. Thank you.

Cant read text file and save it in stl vector with QFile

this is my first question here, i always found the answers i need but today, that "always" has ended haha. My problem is that i'm trying to read a text file with QFile and QTextStream and save the values inside an STL vector. When i try to read the vector, I obtain that is empty(forgive any mistakes with my english, is no my first language). Here i leave you the methods.
bool TGraphic::process_data( void )
{
bool openingOk = false;
QString line;
if(QFile::exists( this->input_file.fileName() ))
{
openingOk = this->input_file.open(QIODevice::Text | QIODevice::ReadOnly);
QTextStream flujo(&input_file);
while(!(flujo.atEnd()))
{
line = flujo.readLine();
this->data.push_back( line.toInt() ); // data is std::vector<int> data;
}
}
return openingOk;
}
The compiler doesn't give me any errors but when i do this
void Ventana::on_pbGraphic_clicked()
{
imgGen = new TGraphic(fileName);
std::vector<int> aux(imgGen->getVector());
bool dataOk, graphicOk;
img = new QPixmap(400, 300);
dataOk = imgGen->process_data();
graphicOk = imgGen->process_graphic(*img);
if(dataOk && graphicOk && !(aux.empty())) // ** THE LAS CONDITION GAVE ME FALSE **
{
//ui->labGraphic->setPixmap(*img);
ui->labNombreArchivo->setText(QString::number(aux[0])); // I TRIED TO GET THE
} // THE FIRST VALUE OF
else // THE VECTOR AND THE
{ // PROGRAM FAILS THERE.
ui->labGraphic->setText("Error.");
}
}
in dialog.cpp i get a false. Can you guys help to see where is the problem? If you need extra information ask me. Thanks!

c++ mfc csv file read

i have a problem with csv file reading. I'm pretty new to mfc and i hope someone can help me. So...i have a button and with it i open file dialog and choose csv file. In csv file i have diferent shapes(rectangle,ellipse,pollygon) with color and position info(separtor is ;). Now i need to show this informations in a ListBox and here i'm stuck. I got so far(code)...and i don't know it's ok and i can't find any good help so i hope someone can give me a hint.
void CDialogDrawing::OnBnClickedButton2()
{
TCHAR filtri[] = _T("CSV files (*.csv)|*.csv||");
CString path;
CFileDialog dlg(TRUE, _T("csv"), _T("*.csv"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filtri);
dlg.m_ofn.lpstrTitle = _T("Open...");
if(dlg.DoModal() == IDOK) //OK
{
path = dlg.GetPathName();
//
CStdioFile readFile;
CFileException fileException;
CString strLine;
if(readFile.Open(path, CFile::modeRead, &fileException))
{
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
}
else
{
CString strErrorMsg;
strErrorMsg.Format(_T("Can't open file %s , error : %u"), path, fileException.m_cause);
AfxMessageBox(strErrorMsg);
}
readFile.Close();
}
}
Trailing semi-colon after the while:
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
remove it as it is equivalent to:
while (readFile.ReadString(strLine)) {}
{
seznamLikov.AddString(strLine);
}
meaning AddString() will be invoked only once, after ReadString() fails.

QFile isn't opening

I wrote the following code for retreiving data from a file(which already exists and permision is also given because i am on Windows OS), and creates items to display data fragments in a List, but the list won't show any thing. More over I figured out even when the file wasn't created, the FILE.EXISTS() function returned true. why is this so?
void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
{
ui->listWidget_2->clear();
QListWidgetItem *itm=new QListWidgetItem;
ui->commentbutton->setEnabled(true);
QFile files("E:/"+QString::number(ui->listWidget->currentRow())+"com.txt");
if(files.exists())
{
if(!files.open(QFile::ReadOnly | QFile::Text))
{
QMessageBox::warning(this,"File Access!!!","The File containing data of the Items and Comments can't be acessed",QMessageBox::Ok);
return;
}
QTextStream in(&files);
QString data(in.readLine());
int x=0;
QString temp;
for(int i=0;;i++)
{
if(data.at(i)!='#' && data.at(i+1)!='#')
{
temp[x]=data.at(i);
x++;
}
else
if(data.at(i)=='#' && data.at(i+1)=='#')
{
x=0;
i++;
itm->setText(temp);
ui->listWidget_2->addItem(itm);
}
if(data.end())
break;
}
files.close();
}
the path at which the files are generated displays:
This is the data stored in 0com.txt file (comment file):
NewYork##London##
Thanks for your time!
1) 0com.txt actually exists. For what current row number in ui->listWidget do you have a "false" files.exists()?
2) data.end() returns a STL-style iterator, while your are incrementing by index. use
if(i>= data.size())
break;
3) Please show the content of "0com.txt" for further debugging