Модераторы: Snowy, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программа для создания электронных книг, Обсуждение исходника 
:(
    Опции темы
xwicked
  Дата 2.7.2011, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Вот вторая моя программа, написанная на 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 - 2.7.2011, 23:53
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 11.7.2011, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Пользователи ОС 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 [email protected]

%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. 
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 17.7.2011, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



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

Следующая версия программы 0.0.80.0.8-rpm. Её ключевой особенностью является импорт html-файла. Вот функция:
Код
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. smile
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 24.7.2011, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



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

Новая версия электронной библиотеки 0.0.90.0.9-rpm0.0.9-deb.

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

При использовании объекта QImage - этот процесс уcкорился на моей тестовой машине раз в 20(!). Код ниже:

Код

              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;

                      }


Код

            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-пакетов и выложу на своём сайте.  Это будет частичный перевод данного руководства начинающего мейнтейнераsmile

Это сообщение отредактировал(а) xwicked - 24.7.2011, 17:39
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 29.7.2011, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



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

В этой версии я сделал одно важное изменение, на которое хотел бы обратить Ваше особое внимание. Это функция "int slotChangeFont()". Там я копирую в переменную QString sText всё выделение:
Код

sText = TextBook->textCursor().selection().toHtml();
Потом заменяю все вхождения модификаторов шрифта: "font-family:", "font-size:", "font-style:", "font-weight:" на значения из диалога шрифта.

Так вот, там должен быть способ в одну единственную строчку. Я даже нашёл его - записал в свою амбарную тетрадь, а сейчас найти не могу  smile  . Прошу помочь в нахождении этого способа, так как "int slotChangeFont()" занимает не много не мало, аж 195 строк(!). Буду благодарен.

Исходный код + сборки.

Что изменилось:
Цитата

- Добавлены значки "Oxygen", распространяемые по лицензии GNU GPL;
- При редактировании шрифта, он изменяется теперь, не для всего текста страницы, а по частям(словам, предложениям, абзацами и т. д.);
- Улучшен импорт HTML-документов, включая копирование изображений, которые преобразуются в формат PNG;
- Изменена стандартная панель - добавлены несколько новых действий;
- Добавлена панель редактирования, в которой продублированы действия из меню "Редактирование", для более удобной работы.
- Счётчик страниц переместился со стандартной панели в строку состояния. 


Это сообщение отредактировал(а) xwicked - 2.8.2011, 19:34
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 10.8.2011, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Вот новая версия 0.1.1 - исходный код + сборки.

Внешний вид:
user posted image

Одно из добавлений - это функция поиска текста по книге:
Код

           while(iNumberPage < ListPages.count())
               {
                 lFind:
                    if(TextBook->find(sFindText) == false)
                        {
                            slotNextPage(); //iNumberPage++

                                if(iNumberPage == ListPages.count() - 1) break;

                            goto lFind;
                        }
                    else break;
               }

QString sFindText - искомый текст;
int iNumberPage - текущая страница
QStringList ListPages - список страниц с текстом.

Для поиска используется "TextBook->find(sFindText)" - будет ли выгода, если использовать функцию поиска в QString непосредственно или использовать контейнер для ускорения? Предполагаю, что сейчас тратится дополнительное время для прорисовки QTextEdit TextBook.

Все новинки:
Цитата

- Добавлена возможность импорта / экспорта простого кодированного текста в формате utf-8;
- Добавлена функция поиска слов по книге;
- Добавлена возможность расширенного редактирования вставленного простого текста;
- Исправлена ошибка, при ответе "Отмена", вопроса о сохранении, при выходе;
- Добавлена панель поиска, с дубликатами команд из меню "Поиск";
- Исправлено несколько ошибок с кнопками панелей;
- Исправлены несколько ошибок при импорте файлов. 


Это сообщение отредактировал(а) xwicked - 10.8.2011, 17:58
PM MAIL WWW ICQ   Вверх
voral
Дата 10.8.2011, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Цитата(xwicked @  29.7.2011,  22:08 Найти цитируемый пост)
Потом заменяю все вхождения модификаторов шрифта: "font-family:", "font-size:", "font-style:", "font-weight:" на значения из диалога шрифта.

Так вот, там должен быть способ в одну единственную строчку. Я даже нашёл его - записал в свою амбарную тетрадь, а сейчас найти не могу  smile  . Прошу помочь в нахождении этого способа, так как "int slotChangeFont()" занимает не много не мало, аж 195 строк(!). Буду благодарен.

Наверно  одну на каждую искомую?
Что то типа такого
Код

sText = TextBook->textCursor().selection().toHtml();
sText.replace(QRegExp("font-family:[^;](;)"),QString("font-family:%1").arg(newFontFamily)).append("\\1");

Точку с запятой я взял в скобки и потом пристыковал при помощи append лишь для демонстрации.
Срезу скажу код не проверял. (регексп надо естественно продумать)

С другой стороны, возможно, будет оптимальным выкинуть выкинуть вообще это все из документа. И использовать метод 
Код

void    QWidget::setStyleSheet ( const QString & styleSheet )



Добавлено через 1 минуту и 6 секунд
Поправка - скобка не туда уехала
Код

sText.replace(QRegExp("font-family:[^;](;)"),QString("font-family:%1").arg(newFontFamily).append("\\1"));

PM MAIL WWW   Вверх
xwicked
  Дата 13.8.2011, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Цитата(voral @ 10.8.2011,  21:06)
... С другой стороны, возможно, будет оптимальным выкинуть выкинуть вообще это все из документа. И использовать метод 
Код

void    QWidget::setStyleSheet ( const QString & styleSheet )

...

Покажите, пожалуйста, простейший пример с одним словом. Возможно, это то, что нужно.
PM MAIL WWW ICQ   Вверх
voral
Дата 13.8.2011, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Похоже я прогнал (сам не пользовался этим) тут скорее для использования css в построении интерфейса программы и виджетов. Подробнее в асситенте qthelp://com.trolltech.qt.473/qdoc/stylesheet-examples.html    (Qt Style Sheets Examples)


Вам же могу предложить следующий вариант. 
в документе перед тегом </head> вставляете либо

Код

<style type="text/css">
.....
</styles>

либо в ресурсы кладете файл таблицы стилей. А потом  вставляете подставляете линк.
Пример.
dialog.cpp
Код

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    QTextBrowser *text1 = new QTextBrowser();
    text1->setHtml("<html><head><style>body{font-size:18pt;}</style></head><body><h1>Test</h1>My test label</body></html>");
    QTextBrowser *text2 = new QTextBrowser();
    text2->setHtml("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"qrc:/styles.css\"></head><h1>Test</h1>My test label</html>");
    QHBoxLayout * la = new QHBoxLayout();
    this->setLayout(la);
    la->addWidget(text1);
    la->addWidget(text2);
}
 
styles.css (в ресурсах, но можно и загружать из файла)
Код

h1{
   color:green;
}


Добавлено @ 23:39
вот вам на всякий пожарный тестик

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  test.zip 3,58 Kb
PM MAIL WWW   Вверх
xwicked
  Дата 14.8.2011, 06:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Цитата(voral @ 13.8.2011,  23:42)
Похоже я прогнал (сам не пользовался этим) ...

Да, я так и понял, так как я вчера 40 минут посидел - и нашёл этот способ  smile  , но я его так и не записал тогда. Предположил, что он есть, думая, что глупо было бы это не предусмотреть  smile Вот он:
Код

         QFont TextFont;
         TextFont = QFontDialog::getFont(&Accept, TextFont);

         QTextCharFormat tcf;
         tcf.setFont(TextFont);

         TextBook->textCursor().setCharFormat(tcf);

PM MAIL WWW ICQ   Вверх
xwicked
  Дата 27.8.2011, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



В версии 0.1.2, была реализована возможность добавления в базу данных библиотеки произвольной информации, в виде ссылок на отдельные файлы. Что представляет собой достаточно хорошее улучшение, так как преподавателю можно будет совершать меньше движений, при создании учебника.

Эта возможность позволит не только сократить время создания учебника, но и послужит отличным расширением возможностей программы, при использовании материалов, содержащихся в отдельных ссылках на файлы, как дополнение к создаваемому учебнику. Например, к книге о художнике, можно будет хранить галерею с изображениями(его работами) в разделе "Фотографии".

Все изменения:
Цитата

- Появилась возможность добавления дополнительной информации произвольного содержания, в виде ссылок на отдельные файлы;
- Добавлена возможность выбора пользователем варианта сохранения книги с паролем или без него;
- Добавлена защита режима редактирования программы отдельным паролем, с возможностью его будущего изменения;
- Добавлена возможность сохранения состояния показа инструментальных панелей после выхода из программы;
- Исправлена ошибка отсутствия изображений, при импорте книги из формата XWB;
- Исправлена ошибка неэкспортирования в форматы XWB, HTML, импортированной книги;
- Исправлена ошибка отсутствия расширения .txt, когда оно явно не указано, при экспорте в текстовый формат.
Исходник + сборки. Дабы быть уверенным в том, что файлы не побились, при закачке, я добавил текстовик с md5-контрольными суммами.
Git-репозиторий:
Цитата

git://klen-library.git.sourceforge.net/gitroot/klen-library/klen-library (read-only) 

PM MAIL WWW ICQ   Вверх
Vasya2904
Дата 6.9.2011, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 20.8.2011

Репутация: нет
Всего: нет



Привет! Несколько моих пожеланий и замечаний. Скачал последнюю версию. Какой-то глюк с паролем, в хелпе написано, что по умолчанию пароль: Password, он почему-то не всегда принимается. Перелистывание страниц, можно сделать ещё каким-нибудь более удобным способом, например на стрелочках, с мышкой не всегда удобно. В содержание можно добавить ссылки на все главы и части. Немного странно сделана возможность открытия книг. Было бы удобнее если в пункте открыть открывался браузер, а не папка программы. Найденный текст неплохо как-нибудь выделять. В целом всё отлично. Буду следить за проектом. Желаю успехов и удачи! 

Это сообщение отредактировал(а) Vasya2904 - 6.9.2011, 11:19
PM MAIL ICQ Skype   Вверх
xwicked
  Дата 10.9.2011, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Цитата(Vasya2904 @ 6.9.2011,  11:09)
Привет! Несколько моих пожеланий и замечаний. Скачал последнюю версию. Какой-то глюк с паролем, в хелпе написано, что по умолчанию пароль: Password, он почему-то не всегда принимается. Перелистывание страниц, можно сделать ещё каким-нибудь более удобным способом, например на стрелочках, с мышкой не всегда удобно. В содержание можно добавить ссылки на все главы и части. Немного странно сделана возможность открытия книг. Было бы удобнее если в пункте открыть открывался браузер, а не папка программы. Найденный текст неплохо как-нибудь выделять. В целом всё отлично. Буду следить за проектом. Желаю успехов и удачи!

Здаров! 
Пароль принимается всегда. Просто, сначала спрашивается пароль режима программы, а затем, если открыта книга, то и пароль книги, хотя там красуется сейчас надпись просто "Введите пароль". Вот и всё! А пароль книги нигде не задокументирован, так как в примере авторская разработка и она защищена правами и изменение её может носить только характер обучения возможностям программы.
Программной реализации содержания пока-что нет, только текст.
В пункте "Открыть", открывается содержимое базы данных библиотеки. Браузер никак не подходит.
PM MAIL WWW ICQ   Вверх
Vasya2904
Дата 11.9.2011, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 20.8.2011

Репутация: нет
Всего: нет



А на книге пароль другой? Я захожу в программу, пишет "введите пароль", я ввожу, всё нормально, открываю книгу, опять просит пароль, я ввожу, не прокатывает, книга не открывается. Но это только в режиме редактирования, в режиме просмотра всё нормально. А содержание планируется? Значит только через импорт книги открывать?
PM MAIL ICQ Skype   Вверх
xwicked
  Дата 16.10.2011, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Версия 0.1.3 содержит добавление защиты документов дополнительной информации от случайного изменения в режиме просмотра:
Код
              connect(ListAdditionallyWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotRunFile()));
       
          void ListAdditionally::slotRunFile()
          {
              if(*sItem == tr("Documents") && gRegime == true)
                  {
                      QString sTmp;
                      sTmp = ListAdditionallyWidget->item(ListAdditionallyWidget->currentRow())->text();
                      int ipos = sTmp.lastIndexOf("/") + 1;
                      sTmp.remove(0, ipos);
                      QFile ifile(ListAdditionallyWidget->item(ListAdditionallyWidget->currentRow())->text());
                      QDataStream idata(&ifile);
                      QByteArray bfile;
                      ifile.open(QIODevice::ReadOnly);
                      bfile = ifile.readAll();
                      QFile ofile("/tmp/xwel/tempfile/" + sTmp);
                      QDataStream odata(&ofile);
                      ofile.open(QIODevice::WriteOnly);
                      ofile.write(bfile);
                      ifile.close();
                      ofile.close();
                      QDesktopServices::openUrl(QUrl::fromLocalFile("/tmp/xwel/tempfile/" + sTmp));//Открытие копии документа
                  }
               else
      //Открытие оригинала документа
               QDesktopServices::openUrl(QUrl::fromLocalFile(ListAdditionallyWidget->item(ListAdditionallyWidget->currentRow())->text()));
          }
То бишь, происходит простое копирование во временный файл документа и его запуск. Но, есть одно небольшое ограничение, при использовании такого подхода(bfile = ifile.readAll();) - файл читается в переменную полностью и он не должен быть слишком большим. А все изменения выглядят вот так:
Цитата
- Исправлена ошибка возможной потери пароля, при экспорте;
- Добавлена защита документов дополнительной информации в режиме просмотра от случайного изменения;
- Появилась функция экспорта всех книг;
- Исправлена ошибка неполного показа длинных названий книг или издательств в списке книг;
- В окне "О программе" все ссылки, для удобного поиска, изменили цвет на синий;
- Исправлена ошибка возможности редактирования списка книг в режиме просмотра;
- В таблицу списка книг добавлены пункты: "Категория", "Подкатегория";
- Исправлена ошибка неудаления книги из базы, при удалении её из списка книг;
- В меню "Помощь" добавились пункты: "Пожертвовать" и "Получить исходный код".

PM MAIL WWW ICQ   Вверх
xwicked
  Дата 20.11.2011, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



В версии 0.1.4 добавилась функция печати: 
Код
void ElectronicLibrary::slotPrint()
{
    QPrinter printer;
    QPrintDialog *pPrintDialog = new QPrintDialog(&printer);

    if(pPrintDialog->exec() == QDialog::Accepted)
    {
        QPainter painter(&printer);
        QRect r(painter.viewport());

        if(ListPages.count() > 0)
        {

            for(int i = 0; i < ListPages.count(); i++)
            {
                TextBook->setHtml(ListPages.at(i));
                painter.drawText(r, TextBook->toPlainText());
                printer.newPage();
            }

            painter.end();
        }

        TextBook->setHtml(ListPages.at(0));
        sbNumberPage.setValue(1);
    }

    delete pPrintDialog;
}
Такой вариант печатает простой текст, без форматирования и изображений.

Все изменения:
Цитата
- Добавлен модуль тестирования "LabFreeTech Тест", для проверки знаний;
- Добавлена функция печати книги;
- Добавлена возможность выравнивания и изменения регистра текста. 

PM MAIL WWW ICQ   Вверх
xwicked
  Дата 31.1.2012, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Версия 0.1.8
Код
//Изменение таблицы
void KlenLibrary::slotResizeTable()
{
    if(gRegimeViewing == true) return;

    InputParametrTable FormInputParametrTable;
    FormInputParametrTable.setWindowTitle(tr("Change table parametrs"));

    if(FormInputParametrTable.exec() == QDialog::Accepted)
    {
        if(FormInputParametrTable.SpinColumnCount->value() > 0
                && FormInputParametrTable.SpinColumnCount->value() > 0)
        {
            TextBook->textCursor().currentTable()->resize(FormInputParametrTable.SpinRowCount->value(),
                                                          FormInputParametrTable.SpinColumnCount->value());
        }
    }
}
currentTable() позволяет работать с таблицей, по текущей позиции курсора в тексте.
Все изменения:
Цитата
- Добавилась возможность создания и редактирования таблиц;
- Исправлена ошибка, не позволяющая сохранять дополнительную информацию, при редактировании;
- Добавлена возможность ввода имени пользователя;
- Добавлен учёт времени работы пользователя с книгой;
- Добавились горячие клавиши;
- Модуль "LabFreeTech Тест" изменил своё название на "Шёлковый тест" и обновился до версии 0.4.1;
- Добавился пункт меню "Сервис", в котором теперь находятся элементы: "Статистика", "Дополнительно", "Тест";
Хочу сообщить о том, что начиная с версии >1.0.0, 30% работы будет сосредоточено на оптимизацию под ООП стандарты smile для лучшей поддержки другими программистами.

P.S. Ещё один очень важный момент: версии 0.1.8 и 0.1.9 - сборки являются минимальными. То есть, чтобы посмотреть на все функции, необходимо программу собрать из исходника . Это делалось для проверки аудитории пользователей на заинтересованность в программе, путем отправки мне запроса на получение исходного кода. Что было не очень удачной идеей и, с версии 0.2.5, сборки программы уже снова полнофункциональны. Прошу извинить меня за данное неудобство  smile  .
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 11.2.2012, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



В версии 0.1.9 добавлена работа с несколькими библиотеками-базами(как и в тесте   smile  ) и возможность резервировать со сжатием:
Код
void KlenLibrary::slotBackupLibrary()
{
    QString sNameBackupLibrary = QFileDialog::getSaveFileName(0, tr("Backup library"), "", "*.xwlbz");

    if(sNameBackupLibrary == "") return;
    if(sNameBackupLibrary.indexOf(".xwlbz") == -1) sNameBackupLibrary += ".xwlbz";

    QFile ifile(sNameLibrary);
    ifile.open(QIODevice::ReadOnly);
    QByteArray baExport;
    baExport = ifile.readAll();
    ifile.close();
    baExport = qCompress(baExport, 9);//Сжатие данных - 9-ая степень
    QFile ofile(sNameBackupLibrary);
    ofile.open(QIODevice::WriteOnly);
    ofile.write(baExport);
    ofile.close();
}

void KlenLibrary::slotRestoreLibrary()
{
    QString sNameBackupLibrary = QFileDialog::getOpenFileName(0, tr("Open backup"), "", "*.xwlbz");

    if(sNameBackupLibrary == "") return;

    QFile ifile(sNameBackupLibrary);
    ifile.open(QIODevice::ReadOnly);
    QByteArray baImport;
    baImport = ifile.readAll();
    ifile.close();
    baImport = qUncompress(baImport);//Извлечение данных из архива

    sNameBackupLibrary = QFileDialog::getSaveFileName(0, tr("Restore library"), "", "*.xwlb");

    if(sNameBackupLibrary.indexOf(".xwlb") == -1) sNameBackupLibrary += ".xwlb";
    if(sNameBackupLibrary == "") return;

    QFile ofile(sNameBackupLibrary);
    ofile.open(QIODevice::WriteOnly);
    ofile.write(baImport);
    ofile.close();
}
Несколько изменений:
Цитата
  - Добавилась возможность резервировать базу данных библиотеки(со сжатием до 5-ти раз(!));
  - Добавлена возможность работы с несколькими библиотеками;
  - Добавлена поддержка полного форматирования текста при печати книги;
  - Добавлено cжатие(до 5-ти раз(!)) импортированной книги в формате xwb.
  - Изменились несколько элементов меню;
Скачать
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 17.2.2012, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Оптимизирована функция изменения шрифта:
Код
        bool Accept;
        QFont TextFont;
        TextFont = TextQuestion->textCursor().charFormat().font();
        TextFont = QFontDialog::getFont(&Accept, TextFont);

        if(Accept)
        {
            QTextCharFormat tcf;
            tcf.setFont(TextFont);
            TextQuestion->textCursor().setCharFormat(tcf);
            cbFont.setCurrentFont(TextFont);
        }
        else return 1;
 и другие изменения.
Скачать
Это последняя версия. В Git создана ветка current теперь, все свежие изменения будут там.
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 3.4.2012, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



Здравствуйте! Новый код. Версия 1.0.0 - это первая версия, в которой можно нормально работать с изображениями. Их количество теперь будет ровно таким, каким и должно быть, не больше. 
Повышена безопасность программы перемещением некоторых переменных в секцию private: Теперь доступ к ним осуществляется из методов:
Код
...

int TTextBook::isCountPages() const
{
    return ListPages.count();
}

int TTextBook::isNumberBook() const
{
    return i_NumberBook;
}

void TTextBook::setNumberBook(int iNumberBook)
{
    i_NumberBook = iNumberBook;
}

int TTextBook::isYear() const
{
    return i_Year;
}

void TTextBook::setYear(int iYear)
{
    i_Year = iYear;
    sYear.setNum(iYear);
}

int TTextBook::isCurrentPage() const
{
    return i_CurrentPage;
}

void TTextBook::setCurrentPage(int iCurrentPage)
{
    i_CurrentPage = iCurrentPage;
}

int TTextBook::isModeWork() const
{
    return b_ModeWork;
}

void TTextBook::setModeWork(bool bModeWork)
{
    b_ModeWork = bModeWork;
}

QByteArray TTextBook::isPassword() const
{
    return ba_Password;
}

void TTextBook::setPassword(QByteArray baPassword)
{
    ba_Password = baPassword;
}
...

//Исправлена печать - печатается весь текст :)
void TTextBook::slotPrint()
{
    QPrinter printer;
    QPrintDialog *pPrintDialog = new QPrintDialog(&printer);
    QTextDocument *textDoc = new QTextDocument;
    QString sPrint;

    if(pPrintDialog->exec() == QDialog::Accepted)
    {
        sPrint = makeOneHTML();

        QImage textImage;

        for (int i = 0; i < ListImages.count(); i++)
        {
            textImage.loadFromData(ListImages.at(i));
            textDoc->addResource(QTextDocument::ImageResource, QUrl(slNumberImages.at(i)), textImage);
        }

        textDoc->setHtml(sPrint);
        textDoc->print(&printer);
    }

    delete textDoc;
    delete pPrintDialog;
}
Цитата
- Оптимизирована скорость загрузки книги до 10 раз;
- Исправлена невозможность нормальной работы с изображениями в книге;
- Добавлен экспорт книги в PDF, PostScript, RTF;
- Исправлена печать книги, теперь печатается весь текст;
- Добавлено шифрование файла книги в формате xwb;
- Модуль Шёлковый тест обновился до версии 1.0.0;
- Добавлена возможность проверки наличия новой версии через интернет
Всего 27 изменений. Скачать:
Теперь исходник одним файлом. Вся информация по сборке rpm и deb-пакетов находится внутри.
PM MAIL WWW ICQ   Вверх
xwicked
  Дата 2.2.2013, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 9.4.2010
Где: Старый Оскол

Репутация: нет
Всего: 1



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

Новая версия. 1.0.5. Тут прошу особо протестировать Mac- и Linux-установщики, так как Linux-пакетов больше нет. Скачать
Цитата("Изменения")
- Исправлена ошибка исчезновения всех изображений, при вставке новой страницы;
- Исправлена ошибка когда, при повторном открытии книги, страницы книг объединялись;
- Исправлена ошибка невозможности создания новой книги из списка книг;
- Добавлен пакетный импорт всех книг из указанной папки в базу библиотеки;
- Добавлено сохранение положений панелей инструментов при выходе из программы;
- Удалена совместимость с базами библиотеки версий 0.1.9 и 0.2.5;
- Из сборки удалён модуль «Шёлковый тест». Его теперь нужно скачивать отдельно;

Благодарю!
PM MAIL WWW ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Совместные проекты/поиск партнёров"
Snowy
Poseidon

Внимание:
В этом форуме обсуждаются вопросы только по совместным проектам, когда Вы хотите найти партнёров или стать участником проекта.
Запрещается размещение заказов на написание программ, поиск работников (для этого есть раздел "Работа") и реклама своих сетевых ресурсов.

Этот раздел только для проектов в которых Вы будете выступать в качестве исполнителя!

Темы и сообщения, не удовлетворяющие данным правилам, будут удаляться на основании пункта 3 Правил форума!

  • Человек, создающий тему, становится руководителем проекта. Все вопросы о разработке решаются с его согласия.
  • Публикация предложения к сотрудничеству считается защищённым авторскими правами и не может разрабатываться без согласия с руководителем проекта.
  • Конечный продукт должен содержать указание на всех участников и Vingrad.

  • Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, Poseidon

     
    0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
    0 Пользователей:
    « Предыдущая тема | Совместные проекты/поиск партнёров | Следующая тема »


     




    [ Время генерации скрипта: 0.1290 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


    Реклама на сайте     Информационное спонсорство

     
    По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
    Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.