I have a single translator.cpp source file containing a lot of strings. These have been been translated to various languages using Qt Linguist. Now I want to split the single file into multiple files:
Old structure:
class Translator
{
QString str1 = tr("");
QString str2 = tr("");
QString str3 = tr("");
};
New structure:
class Translator1
{
QString str1 = tr("");
};
class Translator2
{
QString str2 = tr("");
};
class Translator3
{
QString str3 = tr("");
};
After splitting the translations are lost. What is the fastest way to split the class while keeping the existing translations?
Regards,
Related
I am trying to populate a QListWidget (in icon view) with a QFileSystemModel. I want to list folders and only files with specific extension. I want to show the preview of my files as their thumbnail, so I am subclassing QIconProvider class and I am setting this to my model.
Before setting my QIconProvider to the model I have already filtered the files that I want on my model, icon(const QFileInfo & info) is called for every file that exists in the listed directory.
I have found a work around checking the extension of the file before returning my custom icon, but I am wondering if thre is a way to avoid this.
m_itemsModel = new QFileSystemModel(this);
m_itemsModel->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
m_itemsModel->setRootPath(QDir::homePath());
QStringList filters = formatsList();
m_itemsModel->setNameFilters(filters);
m_itemsModel->setNameFilterDisables(false);
ui.listView->setModel(m_itemsModel);
m_itemsModel->setIconProvider(new ThumbnailIconProvider(QRect(0, 0, 50, 50)));
my QIconProvider:
ThumbnailIconProvider::ThumbnailIconProvider(const QRect &rect)
: QFileIconProvider() {
m_rect = rect;
}
QIcon ThumbnailIconProvider::icon(const QFileInfo & info) const {
static QStringList filters = formatsList();
QString fileName = info.fileName();
QString extension = "*" + fileName.right(fileName.length() - fileName.lastIndexOf("."));
if (info.isFile() && filters.contains(extension)) {
QString path = info.absoluteFilePath();
FileDetails details = fileDetailsFromPathForRect(path, m_rect);
QPixmap pixmap = QPixmap::fromImage(details.image);
QIcon icon(pixmap);
return icon;
}
else
return QFileIconProvider::icon(info);
}
Any ideas please?
So my code so far reads in lines from a file, stores them in two separate ArrayLists. Now I'm going to have to make each node in a doubly Linked List contain the line's string and the corresponding integer, but since I cant put two ArrayLists in the declaration for a Linked List, I tried making a Tree map where the key is the string and the value is the corresponding integer. Here's the relevant code
public class FileReaderProgram
{
public static void main(String[] args) throws IOException
{
ArrayList<String> words = new ArrayList<String>();
ArrayList<Integer> numbers = new ArrayList<Integer>();
String stringComponent = " ";
int integerComponent = 0;
Scanner in = new Scanner(System.in);
System.out.println("Enter the absolute path of the file");
String fileName = in.next(); //Gets the file from the user
File inFile = new File(fileName);
**Map<String,Integer> lineCombo = new TreeMap<String,Integer>();**
try
{
Scanner fileReader = new Scanner(inFile); //Constructs Scanner for reading the file
fileReader.useDelimiter("\\n");
while (fileReader.hasNextLine())
{
String line = fileReader.nextLine(); //Gets line from the file
Scanner lineScanner = new Scanner(line); //Constructs new scanner to analyize the line
lineScanner.useDelimiter(",");
stringComponent = lineScanner.next(); //Read first word
while (!lineScanner.hasNextInt())
{
stringComponent = stringComponent + " " + lineScanner.next(); //Checks if more than one word part of string
}
integerComponent = lineScanner.nextInt(); //Read in integer
words.add(stringComponent); //Array of Strings, element number corresponding to the line it came from
numbers.add(integerComponent); //Array of Ints, same thing as above
**lineCombo.put(stringComponent, integerComponent);**
}
}
So when I run the file:
example string,1
another example,42
data,200
final,150
it prints out {another example=42, data=200, example string=1, final=150}
Why is it putting the strings in the wrong order?
I am trying to implement copy/cut/paste in a complex application.
I have a QGraphicsScene that can contain QGraphicsItem subtypes of varied subtypes, fairly complex (with Item as a second parent storing custom properties).
I would copy/cut selected items, and paste them back in place.
I already have implemented it using a local version: a list of items.
void copyItemsActionOld()
{
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* newItem = (dynamic_cast<Item*>(qItem))->createItemCopy();
m_itemClipboard.append(newItem);
}
}
On paste, I make a copy of all items in clipboard and add them to the scene. So simple.....
BUT
I need to implement it using the global system clipboard.
I saw that creating a custom mime type is as simple as calling setData on a QMimeData object, after I make up a format name... (I hope that is true)
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QMimeData* _mimeData = new QMimeData;
2 QByteArray _itemData = ?????;
_mimeData->setData(_mimeType, _itemData);
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
3 // then do what ? How do I parse it ?
}
}
}
My questions
1) Are the above fragments for copyItemsAction and pasteItemsAction anywhere close to how clipboard actions should work ?
2) How can I put item data in the QByteArray ?
3) How do I parse the data in QByteArray ?
4) Do I need to register the custom mime-type anywhere else ? (other than what I just did in my two functions); and will it be multi-platform ?
I have already implemented save and load functionality for all items. Something like...
void Item::saveItem(QDataStream &outFile)
{
outFile << type;
outFile << width;
outFile << color.name();
}
Can I use this to place the items data in the QByteArray ? (How ?)
I was on the right track, and I kept adding code to my question until I found how to make it work:
static const QString _mimeType("application/myItem");
void copyItemsAction()
{
QByteArray _itemData;
QDataStream outData(&_itemData, QIODevice::WriteOnly);
outData << selectedItems().size();
foreach(QGraphicsItem* qItem, selectedItems())
{
Item* item = dynamic_cast<Item*>(qItem);
item->saveItem(outData);
}
QMimeData* _mimeData = new QMimeData;
_mimeData->setData(_mimeType, _itemData);
_mimeData->setText("My Items");
QClipboard* _clipboard = QApplication::clipboard();
_clipboard->clear();
_clipboard->setMimeData(_mimeData);
}
void pasteItemsAction()
{
QClipboard* _clipboard = QApplication::clipboard();
const QMimeData* _mimeData = _clipboard->mimeData();
QStringList _formats = _mimeData->formats();
foreach (QString _format, _formats)
{
if (_format == _mimeType)
{
QByteArray _itemData = _mimeData->data(_mimeType);
QDataStream inData(&_itemData, QIODevice::ReadOnly);
int itemsSize;
inData >> itemsSize;
for (int i = 0; i < itemsSize; ++i)
{
Item* item = ...
item->loadItem(inData);
}
}
}
}
So, for question 1, yes I was on the right track;
For questions 2 and 3 - I was able to use a QDataStream to serialize info to/from the QByteArray.
If there is a better / more effective / faster way, I would love to know...
For question 4 - it seems that I can use just about any string, if all I want is to copy/paste within a single instance of my application.
It is also true if I want to use it between multiple applications, multiple instances of my application, or for drag-and-drop - on most platforms. (It does not seem to work between multiple applications/instances in the embedded platform I target.)
Caveat - it fails frequently when another clipboard using application is open, in windows.
I've been trying to write some data to a binary file in c++ using fstream and most examples go like this:
#include <fstream>
class Person{
public:
int age;
char name[50];
}
int main(){
Person joe;
joe.age = 50;
strncpy(joe.name, "Joe Jones");
fstream file("filename.dat", ios_base::binary);
file.write((char*)joe, sizeof(joe));
file.close();
}
This works just as expected but the problem arises when I try to write a more complex structure, mainly one with pointers instead of the actual data.
class Person{
public:
int age;
int *friendsAges;
Person(int friends){
friendsAges = new int[friends];
}
}
When I write the data like before
Person joe(10);
/* Initialize rest of joe */
file.write((char*)joe, sizeof(joe));
the resulting file has 8 bytes of data, 4 for the age and 4 for the address of the friendsAges array or so it seems.
How could I go about writing the actual data that is stored in the array? I have also had this problem when my classes have other classes as members such as a Person having a Car or something like that.
For starters, add a method to your class that will perform the file I/O then you can just call it like so:
Person joe();
Person sally();
fstream file("filename.dat", ios_base::out | ios_base::binary);
joe.serialize(file, true);//writes itself to the file being passed in
sally.serialize(file, true); //write another class to file after joe
file.close();
Then later you could read that same file to populate the class instance:
fstream file("filename.dat", ios_base::in | ios_base::binary);
joe.serialize(file, false); //reads from file and fills in info
sally.serialize(file, false); //reads from file too
file.close();
The method in the class would look something like this:
Person::serialize(fstream &fs, bool bWrite)
{
int ages_length;
if (bWrite) {
fs.write(&age, sizeof(age));
ages_length = ...; //you need to know how long the friendsAges array is
fs.write(&ages_length, sizeof(ages_length)); //write the length to file
fs.write(&friendsAges[0], sizeof(int)*ages_length); //write the variable-sized array to file
fs.write(&name[0], sizeof(char)*50); //write a string of length 50 to file
}
else {
fs.read(&age, sizeof(age));
fs.read(&ages_length, sizeof(ages_length)); //read length of array from file
//TODO: you will need to malloc some space for *friendsAges here
fs.read(&friendsAges[0], sizeof(int)*ages_length); //read-in the variable length array
fs.read(&name[0], sizeof(char)*50); //this only works if string length is always fixed at 50
}
}
I am passing a QVector from one window to another, I want to append the value present in QVector from previous window to a QString in present window. I get the error when I perform the addition no match for 'operator+'.
Here is my code:
Window1.cpp
void SelectOS::processNextButton()
{
if(ui->win32->isChecked()){
QString path;
path = qApp->applicationDirPath()+"/WIN/32Bit";
so->osName.push_back(path);
SelectSoftware *ss = new SelectSoftware();
this->hide();
ss->show();
}
}
QVector<QString> SelectOS::getosName(){
so = new SelectOS();
return so->osName;
}
Window2.cpp
void SelectSoftware::getSoftwareDetails()
{
SelectOS *so = new SelectOS();
SelectSoftware *ss = new SelectSoftware();
ss->os = so->getosName();
QString fileName = ss->os + "/" +SOFTWARELIST; // Here I get the error...
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString msg = "Could not find the file " + fileName;
errorExit(msg);
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
processLine(line.toLower());
}
}
Help me, thanks ...
Assuming SOFTWARELIST is a simple QString:
QString fileName = QString( "%1/%2" )
.arg( ss->os.last() )
.arg( SOFTWARELIST );
This means you are creating a QString with placeholders %1 and %2 where %1 will be replaced by the result of ss->os.last() which returns the last item in the vector and %2 will be replaced by whatever SOFTWARELIST is.
If SOFTWARELIST is a vector as well, you will need to call e.g. .last() on it as well.
QVector is a container class, which holds set of something. In your example set of QString's. So then you try to form a fileName which is a QString you obviously cannot add to a fileName QString list of other Qstring's. (truly saying you can, but not with '+' operator and slightly different code).
Honestly I didn't got straight away why you actually passing QVector if you only need an application path I would suggest to use just QString.