Russian Qt Forum
Ноябрь 23, 2024, 03:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: Программа для создания электронных книг[Обсуждение исходника]  (Прочитано 43344 раз)
xwicked
Гость
« : Июль 03, 2011, 16:11 »

Здравствуйте! Вот вторая моя программа, написанная на C++(Qt). Выношу на обсуждение её и исходник - 0.0.7.

Ссылка на SourceForge.net. Код под GNU GPL v2 - OpenSource.

Она предназначена для создания электронных книг, с централизованным хранением в базе данных SQLite3.

Этот код публикуется впервые. Его не было нигде, включая репозиторий программ Sisyphus от дистрибутива AltLinux. Там был только Клёст-кроссворд(0.1.9, 0.2.0). Комментируем Windows-версия.

Описание:
Страница книги представляет собой одну переменную QString Page.
Текст книги отображается в компоненте QTextEdit TextBook.
Текст в компоненте TextBook имеет форматирование документа HTML. Поэтому редактирование текста страницы осуществляется редактированием html-кода.

Стандартное сохранение идёт в базу данных. Но есть и возможность экспорта в файл.

Изображения хранятся, как в обычной html-странице - отдельно от текста в папке "temp". В тексте указывается путь.
При загрузке книги - во всех страницах происходит перезапись тегов изображения "<img src=":
Код:
QString str1;
int iFirst,
    iLast,
    iLength,
    iSearch;
    for(int i = 0; i < ListPages.count(); i++)
        {
            str1 = ListPages.at(i);
                if(str1.indexOf("<img src=\"") != -1)
                    {
                         int z = 1;
                         iSearch = 0;
                             while(str1.indexOf("<img src=\"", iSearch) != -1)
                                 {
                                          if(z == 1) iSearch = -1;
                                          if(iSearch == -1)
                                              {
                                                   iFirst = str1.indexOf("<img src=\"", 0);
                                                   iLast = str1.indexOf("/temp/Image", 0);
                                                   z++;
                                              }
                                          else
                                              {
                                                   iFirst = str1.indexOf("<img src=\"", iSearch);
                                                   iLast = str1.indexOf("/temp/Image", iFirst);
                                              }
                                      iFirst += 10;
                                      iLength = iLast - iFirst;
                                      str1.remove(iFirst, iLength);
                                      str1.insert(iFirst, "/tmp/xwel");
                                      ListPages.replace(i, str1);
                                      iSearch = iLast;
                                 }
                    }
        }
Это актуально для переносимой версии. В этом случае необходимо будет поменять строку:
Код:
str1.insert(iFirst, "/tmp/xwel");
на
Код:
str1.insert(iFirst, QApplication::applicationDirPath());//Текущая папка, из которой запущено приложение
Пароль книги хранится в открытом виде в переменной QString Password.
Список страниц хранится в списке строк QStringList ListPages.
Изображения хранятся в массиве QByteArray ListImages[255]. Здесь видно, что изображений на всю книгу 255.

Сохранение в базу происходит обычными SQL-запросами:
Код:
strBook = "DROP TABLE Table" + sNumBook + ";";
QueryBook.exec(strBook);
strBook = "CREATE TABLE Table" + sNumBook + " (Pages VARCHAR, Images BLOB);";
QueryBook.exec(strBook);
...
//Сохранение страниц
if(ListPages.count() != 0)
    for(int i = 0; i < ListPages.count(); i++)
        {
           QueryBook.prepare("INSERT INTO Table" + sNumBook + " (Pages) VALUES (?);");
           QueryBook.bindValue(0, ListPages.at(i));
           QueryBook.exec(/*strBook*/);
        }
//Сохранение изображений
    for(int i = 0; i < 75; i++)//Здесь видно - что сохраняются только 75 изображений(!) из 255 :(
        {
              if(ListImages[i].count() != 0)
                 {
                    QueryBook.prepare("INSERT INTO Table" + sNumBook + " (Images) VALUES (?);");
                    QueryBook.bindValue(0, ListImages[i]);
                    QueryBook.exec(/*strBook*/);
                 }
             else break;
 }
Записан
xwicked
Гость
« Ответ #1 : Июль 11, 2011, 23:46 »

Пользователи ОС Linux на RPM-основе, которые захотят сделать свою сборку программы для размещения на собственном сайте или сервере, то вот спекфайл:
Цитировать
Summary: Qt program for creating and reading electronic books.

Summary(ru): Qt программа для создания и чтения электронных книг.

%define version 0.0.7

Group: Education

Name: klen-library

BuildRequires: gcc-c++, libqt4-sql-sqlite >= 4.4.3, libqtgui4 >= 4.4.3, libqt4-core >= 4.4.3

BuildArch: %ix86

Provides: klen-library

Release: alt1

Source: klen-library-%{version}.tar.gz

Url: http://labfreetech.org/index_e.html

Version: %{version}

License: GPLv2

Packager: LabFreeTech.org admin@labfreetech.org

%description
Qt program for creating and reading electronic books.
Supported features: - Creation of a textbook; - Editing of the textbook; - Reading the textbook; - Adding / removing books from the database; - Editing the font of the textbook; - Export and import of books in the file.

%description -l ru
Qt программа для создания и чтения электронных книг.
Поддерживаемые функции: - Создание учебника; - Редактирование учебника; - Чтение учебника; - Добавление/удаление учебников из базы данных; - Редактирование шрифта учебника; - Экспорт и импорт учебников в файл.

%prep

%setup -q

%build
%make_build
#cp -f klen-library debian/klen/opt/klen-library/

%install

cp -Rv klen/ %buildroot/

#rm -rf $RPM_BUILD_ROOT


%clean

rm -rf $RPM_BUILD_ROOT

%files

/usr/bin/*
/usr/share/*

%post

test -e /usr/bin/xwel-0.0.7 || ln -s /usr/bin/xwel-0.0.7 /usr/bin/klen-library-0.0.7
test -e $HOME/Desktop/xwel.desktop || cp -r /usr/share/applications/xwel.desktop $HOME/Desktop/klen-library.desktop

%postun

test -L /usr/bin/klen-library-0.0.7 && rm -r /usr/bin/klen-library-0.0.7
test -e $HOME/Desktop/klen-library.desktop && rm -r $HOME/Desktop/klen-library.desktop
Он находится в архиве, который специально подготовлен. Постараюсь ответить на все возникающие вопросы. Команда для сборки двоичного пакета:
Цитировать
$rpmbuild -bb /home/username/RPM/SPECS/xwel-0.0.7-alt.spec
Предварительно необходимо установить пакет rpm-build. 
Записан
xwicked
Гость
« Ответ #2 : Июль 17, 2011, 21:38 »

Здравствуйте!

Следующая версия программы 0.0.8, 0.0.8-rpm. Её ключевой особенностью является импорт html-файла. Вот функция:
Код
C++ (Qt)
void ElectronicLibrary::OpenHTMLFile()
{
    QString FileNameBook, str, sHTML;
    FileNameBook = QFileDialog::getOpenFileName(0, tr("Book import"), "", "*.html");
 
        if(FileNameBook == "") return;
        else
            {
                QFile ifile(FileNameBook);
                QTextStream istream(&ifile);
                float i = 0;//Величина %
                float ipt,//Численное значние "pt"
              iptc;//Отвечает за таблицу
                iptc = 0;
                ipt = 0;
                ifile.open(QIODevice::ReadOnly);
 
                    while(!ifile.atEnd())
                        {
                            str.append(istream.readLine());
                            str.append(" ");
                            sHTML.append(str);
 
                                if(str.indexOf("<TABLE") != -1) iptc = 1;//Начало таблицы
                                if(str.indexOf("/TABLE>") != -1) iptc = 2;//Конец таблицы
 
                            int j, iptc2;
                            QString s1,s2;
                            s1.clear();
                            s2.clear();
                            iptc2 = 0;
 
               //Поиск элемента обозначения шрифта
                            j = str.indexOf("font-size:");
 
//Если элемент найден и найдено вхождение "pt", то
                                if(j != -1 && str.indexOf("pt", j) != -1)
                                    {
                     //Добавление одной цифры, стоящей за "pt"
                                         s1.append(str.at(str.indexOf("pt", j) - 1));
 
//Если второй символ стоящий за первым числом не пробел, то
                                             if(str.at(str.indexOf("pt", j) - 2) != ' ')
                     //Добавить его как вторую цифру числа шрифта(ex. "14pt")
                         s2.append(str.at(str.indexOf("pt", j) - 2));
 
             //Соединить с первой цифрой в s1. Образовать число.
                                             if(s2 != "") s1.append(s2);
 
                                         bool bOk;
                                         ipt = s1.toFloat(&bOk);
//6pt = 113 = 0.885% от страницы
//16pt = 42 = 2.380% от страницы
//0.1375 - условный средний коэффициент % занимаемого значения 6pt на одной странице, формата A4
//Усреднённая формула нахождения % текущей строки от страницы, формата A4, относительно 6pt
                                         ipt = (ipt / 6) * 0.1375;
                                    }
 
//Поиск элемента обозначения шрифта другой формы
                                if(j == -1)
                                    {
                                        if(str.indexOf("FONT SIZE=1") != -1) j = 1 ;
                                        if(str.indexOf("FONT SIZE=2") != -1) j = 2 ;
                                        if(str.indexOf("FONT SIZE=3") != -1) j = 3 ;
                                        if(str.indexOf("FONT SIZE=4") != -1) j = 4 ;
                                        if(str.indexOf("FONT SIZE=5") != -1) j = 5 ;
                                        if(str.indexOf("FONT SIZE=6") != -1) j = 6 ;
                                        if(str.indexOf("FONT SIZE=7") != -1) j = 7 ;
 
                                            switch(j)//Вычисление процента
                                                {
                                                     case 1:
                                                         ipt = (8 / 6) * 0.1375;
                                                     case 2:
                                                         ipt = (10 / 6) * 0.1375;
                                                     case 3:
                                                         ipt = (12 / 6) * 0.1375;
                                                     case 4:
                                                         ipt = (14 / 6) * 0.1375;
                                                     case 5:
                                                         ipt = (18 / 6) * 0.1375;
                                                     case 6:
                                                         ipt = (24 / 6) * 0.1375;
                                                     case 7:
                                                         ipt = (36 / 6) * 0.1375;
                                                }
                                    }
 
                            i += ipt;//Суммирование процента
 
                                if(i >= 100)//Если набралось 100%
                                    {
                                        if(iptc == 0)//Если нет таблицы в конце страницы
                                            {
                                                 sHTML.append("</body></html>");
                                                 ListPages << sHTML;
                                                 sHTML.clear();
                                                 sHTML.append("<html><body>");
                                                 i = 0;
                                            }
                                        else
                                            {
       //Если таблица была закрыта на данной странице
                                                 if(iptc == 2)
                                                     {
                                                          sHTML.append("</body></html>");
                                                          ListPages << sHTML;
                                                          sHTML.clear();
                                                          sHTML.append("<html><body>");
                                                          i = 0;
                                                          iptc = 0;//Значение = таблиц нет
                                                     }
                                            }
                                    }
 
                            str.clear();
                        }
 
                    if(sHTML != "") ListPages << sHTML << "</body></html>";
 
                ifile.close();
 
                    if(gRegimeViewing == true) return;
}
Она производит разбивку на страницы, подсчитывая условное значение количества строк располагаемых на странице, формата A4. Была ещё задумка подсчитать количество символов в строке но, пока решил остановиться на таком варианте.

Разбивая страницы, она переносит всю таблицу на одну страницу до конца, даже, если таблица физически должна быть на 2-х или более страницах.

Импортируются пока только html-страницы, созданные в OpenOffice. Это делалось для того, чтобы преподаватели, у которых имеются методички в формате MSWord(*.doc) могли наиболее быстро перегнать своё пособие в мою программу.

Как Вам эта функция и есть ли возможность всё это максимально упростить? Благодарю за ответ.

P.S. Следующим сообщением я выложу архив для сборки deb-пакетов, дистрибутивов ОС Linux Debian, Ubuntu. Улыбающийся
« Последнее редактирование: Июль 17, 2011, 21:41 от xwicked » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #3 : Июль 17, 2011, 21:44 »

Интересно)
Лично мне если нужно что-либо такое написать, использую LaTeX.
Ничего лучше для написания статей, книг и т.п. имхо, пока не придумали.
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xwicked
Гость
« Ответ #4 : Июль 22, 2011, 16:06 »

Интересно)
Лично мне если нужно что-либо такое написать, использую LaTeX.
Ничего лучше для написания статей, книг и т.п. имхо, пока не придумали.
При поверхностном обзоре моей программы может сложиться данная иллюзия.
Назначение программ далеко не одинаковое.

P.S. Благодарю за попытку сравнения Клён-библиотеки с LaTex. Ещё одна хорошая новость в адрес моей программы Улыбающийся
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Июль 22, 2011, 17:07 »

Интересно)
Лично мне если нужно что-либо такое написать, использую LaTeX.
Ничего лучше для написания статей, книг и т.п. имхо, пока не придумали.
При поверхностном обзоре моей программы может сложиться данная иллюзия.
Назначение программ далеко не одинаковое.

P.S. Благодарю за попытку сравнения Клён-библиотеки с LaTex. Ещё одна хорошая новость в адрес моей программы Улыбающийся
Я не чего не имею против этого проекта, напротив)

Просто если мне нужно написать, скажем методичку, где будет куча формул, ссылок на литературу и т.п. то какие приимущества я получу от использования Вашей программы в сравнении с LaTeX?
Цели, как мне видятся у этих двух инструментов одни? Или я ошибаюсь?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xwicked
Гость
« Ответ #6 : Июль 22, 2011, 17:32 »

...
Я не чего не имею против этого проекта, напротив)

Просто если мне нужно написать, скажем методичку, где будет куча формул, ссылок на литературу и т.п. то какие приимущества я получу от использования Вашей программы в сравнении с LaTeX?
Цели, как мне видятся у этих двух инструментов одни? Или я ошибаюсь?
Думаю, в Вашем случае никаких преимуществ не будет, если Вы не преподаватель в образовательном учреждении.
В первую очередь нужно обратить внимание на использование базы данных для хранения методичек.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #7 : Июль 22, 2011, 17:43 »

...
Я не чего не имею против этого проекта, напротив)

Просто если мне нужно написать, скажем методичку, где будет куча формул, ссылок на литературу и т.п. то какие приимущества я получу от использования Вашей программы в сравнении с LaTeX?
Цели, как мне видятся у этих двух инструментов одни? Или я ошибаюсь?
Думаю, в Вашем случае никаких преимуществ не будет, если Вы не преподаватель в образовательном учреждении.
В первую очередь нужно обратить внимание на использование базы данных для хранения методичек.
Предположим, я преподователь в образовательном учереждении. И мне постоянно нужно писать всякие там методички и прочие учебн. пособия.
Вот я по привычке пишу всё в техе и сохраняю это всё на диске.
Зачем мне база данных? Я и так знаю где что лежит)
Ваша фишка, как я понял, в консолидированном управлении всеми документами и возможностью тут-же что-то в них править из одной программы?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xwicked
Гость
« Ответ #8 : Июль 22, 2011, 18:31 »

...
Предположим, я преподователь в образовательном учереждении. И мне постоянно нужно писать всякие там методички и прочие учебн. пособия.
Вот я по привычке пишу всё в техе и сохраняю это всё на диске.
Зачем мне база данных? Я и так знаю где что лежит)
Ваша фишка, как я понял, в консолидированном управлении всеми документами и возможностью тут-же что-то в них править из одной программы?
Именно. Вы знаете, где что лежит. Я сам видел работу преподавателей в колледже. Тут дело не в способностях, а в учебной нагрузке, при которой забываются достаточно простые вещи. Она призвана минимизировать работу по нахождению, правке и дальнейшем совершенствовании пособия; Чтобы избежать ситуаций по двойной работе или потере уже сделанной.

В MSWord не используются более 50% функций.
OOWrite на ненастроенной java - работает дольше двоичного исполняемого файла без виртуальных машин.
Клён-библиотека собирает минимум необходимых функций, которые будут абсолютно платформенно-независимы, чтобы не править ни строчки кода при переносе на другие платформы.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #9 : Июль 22, 2011, 18:50 »

...
Предположим, я преподователь в образовательном учереждении. И мне постоянно нужно писать всякие там методички и прочие учебн. пособия.
Вот я по привычке пишу всё в техе и сохраняю это всё на диске.
Зачем мне база данных? Я и так знаю где что лежит)
Ваша фишка, как я понял, в консолидированном управлении всеми документами и возможностью тут-же что-то в них править из одной программы?
Именно. Вы знаете, где что лежит. Я сам видел работу преподавателей в колледже. Тут дело не в способностях, а в учебной нагрузке, при которой забываются достаточно простые вещи. Она призвана минимизировать работу по нахождению, правке и дальнейшем совершенствовании пособия; Чтобы избежать ситуаций по двойной работе или потере уже сделанной.

В MSWord не используются более 50% функций.
OOWrite на ненастроенной java - работает дольше двоичного исполняемого файла без виртуальных машин.
Клён-библиотека собирает минимум необходимых функций, которые будут абсолютно платформенно-независимы, чтобы не править ни строчки кода при переносе на другие платформы.
Идея хорошая)
Но мне не нравится, что Вы, фактически, навязываете свой редактор. Почему бы не дать возможность пользователю самому выбирать при этом ту программу для отображения и редактирования к которой он привык?
Сделать нечто подобное Git, в смысле) Некий менеджер по контролю документов)
А так, едва ли Клён-библиотека заинтересует массы)   
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
brankovic
Гость
« Ответ #10 : Июль 22, 2011, 19:08 »

Сделать нечто подобное Git, в смысле) Некий менеджер по контролю документов)

тогда чем проводник + гуи клиент гита + любимый редактор не устраивают?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Июль 22, 2011, 19:11 »

Сделать нечто подобное Git, в смысле) Некий менеджер по контролю документов)

тогда чем проводник + гуи клиент гита + любимый редактор не устраивают?
Смеющийся Да, тоже вот сейчас об этом подумал)

Хотя Git это несколько не совсем то.
Здесь имеется ввиду контроль множества различных дукументов, не связанных между собой. 
« Последнее редактирование: Июль 22, 2011, 19:24 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xwicked
Гость
« Ответ #12 : Июль 22, 2011, 20:05 »

...
Идея хорошая)
Но мне не нравится, что Вы, фактически, навязываете свой редактор. Почему бы не дать возможность пользователю самому выбирать при этом ту программу для отображения и редактирования к которой он привык?
Сделать нечто подобное Git, в смысле) Некий менеджер по контролю документов)
А так, едва ли Клён-библиотека заинтересует массы)   
Самодостаточность - важный фактор.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #13 : Июль 22, 2011, 20:19 »

Цитировать
Самодостаточность - важный фактор.
Весьма сомнительный аргумент в отношении Вашей задумки)
Да и никакой самодостаточности никогда не хватит) Прогресс не стоит на месте.
Рискуете что Ваша программа будет востребована очень узким кругом лиц.

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
xwicked
Гость
« Ответ #14 : Июль 24, 2011, 21:44 »

Теперь и счастливым обладателям дистрибутивов GNU / Linux Debian и его производным(Ubuntu), предоставилась возможность попробовать себя в качестве разработчиков ПО.

Новая версия электронной библиотеки 0.0.9, 0.0.9-rpm, 0.0.9-deb.

Серьёзным изменением в данной версии является ускорение загрузки книги из базы данных. Это связано с выгрузкой изображений из базы на диск в папку. Сначала я не знал, как сделать лучше, поэтому сделал выгрузку по одному байту, что занимало большой промежуток времени.

При использовании объекта QImage - этот процесс уcкорился на моей тестовой машине раз в 20(!). Код ниже:
Код
C++ (Qt)
             for(int i = 0; i < 75; i++)
                 if(ListImages[i].count() != 0)
                     {
                         QString sNumImage;
                         QByteArray sByteImage;
                         sByteImage.clear();
                         sNumImage.setNum(i);
 
                             if(i >= 0 && i <= 9) sNumImage.insert(0,"0");
 
                         ifile.setFileName("/tmp/xwel/temp/Image" + sNumImage + ".png");
                         QDataStream sifile(&ifile);
                         uchar cdata;
                         ifile.open(QIODevice::WriteOnly);
                         sByteImage.append(ListImages[i]);
 
                             while(sByteImage.count() != 0)
                                 {
                                     cdata = uchar(sByteImage.at(0));
                                     sifile << cdata;
                                     sByteImage.remove(0, 1);
                                 }
 
                             if(i > SelectWordDialog->value()) SelectWordDialog->setValue(i);
 
                         QApplication::processEvents();
 
                             if(SelectWordDialog->wasCanceled()) break;
                     }
Код
C++ (Qt)
           for(int i = 0; i < CountImages; i++)
               if(ListImages[i].count() != 0)
                   {
                       QString sNumImage;
                       QByteArray sByteImage;
                       sByteImage.clear();
                       sNumImage.setNum(i);
 
                           if(i >= 0 && i <= 9) sNumImage.insert(0,"0");
 
                       sByteImage.append(ListImages[i]);
                       QImage ImageSave;
                       ImageSave.loadFromData(sByteImage);
                       ImageSave.save("/tmp/xwel/temp/Image" + sNumImage, "PNG");
 
                           if(i > SelectWordDialog->value()) SelectWordDialog->setValue(i);
 
                       QApplication::processEvents();
 
                           if(SelectWordDialog->wasCanceled()) break;
                   }
Для сборки deb-пакета необходимо наличие установленных пакетов: autotools-dev, dh-make, fakeroot и другие.
Команда сборки:
Цитировать
user@pc:/klen-library-0.0.9-deb$ dpkg-buildpackage -rfakeroot
ЗЫ: Возможно скоро напишу краткое руководство по сборке deb-пакетов и выложу на своём сайте.  Это будет частичный перевод данного руководства начинающего мейнтейнера. Улыбающийся
Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.251 секунд. Запросов: 23.