diff options
author | Petar Petrov <ppetrov@paju.oulu.fi> | 2012-09-11 23:42:31 -0500 |
---|---|---|
committer | Robby Workman <rworkman@slackbuilds.org> | 2012-09-11 23:53:42 -0500 |
commit | df5b7aedb981bee9a7a87ea2ac775a53caa4a444 (patch) | |
tree | 345960e77e0427d45231a7c9ad920415ba5b3e7b /office | |
parent | dea576fec344061d75fce02c9b07ee7d14596a32 (diff) |
office/gbgoffice: Build fixes and miscellaneous cleanups
Signed-off-by: Robby Workman <rworkman@slackbuilds.org>
Diffstat (limited to 'office')
-rw-r--r-- | office/gbgoffice/README | 20 | ||||
-rw-r--r-- | office/gbgoffice/gbgoffice.SlackBuild | 53 | ||||
-rw-r--r-- | office/gbgoffice/gbgoffice.desktop | 4 | ||||
-rw-r--r-- | office/gbgoffice/gbgoffice.info | 6 | ||||
-rw-r--r-- | office/gbgoffice/patches/03_multidir.patch | 589 | ||||
-rw-r--r-- | office/gbgoffice/patches/04_fix_fsf_address.patch | 29 | ||||
-rw-r--r-- | office/gbgoffice/patches/05_gcc4.1.patch | 14 | ||||
-rw-r--r-- | office/gbgoffice/patches/06_const-chars.patch | 289 | ||||
-rw-r--r-- | office/gbgoffice/patches/07_gcc4.3.patch | 14 | ||||
-rw-r--r-- | office/gbgoffice/patches/08_fix_const_conversion.patch | 17 | ||||
-rw-r--r-- | office/gbgoffice/patches/09_deprecated_SigC.patch | 41 | ||||
-rw-r--r-- | office/gbgoffice/patches/10_workhelper-buttonbox.patch | 16 | ||||
-rw-r--r-- | office/gbgoffice/patches/11_explicit-linkage.patch | 29 | ||||
-rw-r--r-- | office/gbgoffice/slack-desc | 14 |
14 files changed, 1094 insertions, 41 deletions
diff --git a/office/gbgoffice/README b/office/gbgoffice/README index f4c96e2b09cf..a00538c9b641 100644 --- a/office/gbgoffice/README +++ b/office/gbgoffice/README @@ -1,11 +1,13 @@ -GBGoffice provides an easy to use GTK interface for the dictionaries -from the Bulgarian Office project. It supports all five of them: +The GTK BG Office assistant (Gbgoffice) is part of the Bulgarian +Office project (Bgoffice). Gbgoffice provides an easy to use GTK+ +interface for the Bgoffice dictionaries. It supports all five of them: -- English <=> Bulgarian -- Polytechnical -- Computer Terms -- Thesaurus -- Dialect +1) Dual Bulgarian English dictionary +2) Dictionary of computer terms +3) Dialect dictionary ;) +4) Polytechnical English Bulgarian dictionary +5) Thesaurus -If you are using KDE, you might want to try kbgoffice (QT4 interface), -instead. +After gbgoffice is installed, you need full-pack for the dictionaries. + +NOTE: If you use KDE, you may want kbgoffice (QT4 interface) instead. diff --git a/office/gbgoffice/gbgoffice.SlackBuild b/office/gbgoffice/gbgoffice.SlackBuild index c4726e69e817..b1520fc3806e 100644 --- a/office/gbgoffice/gbgoffice.SlackBuild +++ b/office/gbgoffice/gbgoffice.SlackBuild @@ -1,21 +1,30 @@ #!/bin/sh # Slackware build script for gbgoffice -# Written by Petar Petrov, <ppetrov@paju.oulu.fi> and -# hereby submitted to the public domain -# Based on the gbgoffice PKGBUILD from Archlinux AUR -# (http://aur.archlinux.org/packages.php?ID=45316). -# PKGBUILD submitter and maintainer is phible. Patches -# are from Debian. Thank you! - -# THIS SLACKBUILD IS DISTRIBUTETD IN THE HOPE OF BEING -# USEFUL BUT WITHOUT ANY WARRANTY. THE AUTHOR IS _NOT_ -# RESPONSIBLE FOR ANY DAMAGE OR DATA LOSS CAUSED BY IT. +# Copyright 2011-2012 Petar Petrov, ppetrov@paju.oulu.fi +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PRGNAM=gbgoffice VERSION=${VERSION:-1.4} -BUILD=${BUILD:-1} +BUILD=${BUILD:-2} TAG=${TAG:-_SBo} if [ -z "$ARCH" ]; then @@ -51,7 +60,7 @@ rm -rf $PKG mkdir -p $TMP $PKG $OUTPUT cd $TMP rm -rf $PRGNAM-$VERSION -tar xvf $CWD/$PRGNAM-$VERSION.tar.gz +tar xvf $CWD/${PRGNAM}_${VERSION}.orig.tar.gz cd $PRGNAM-$VERSION chown -R root:root . find . \ @@ -60,12 +69,15 @@ find . \ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ -exec chmod 644 {} \; -# Apply the Debian patches. Thank you Debian! -patch -p1 -i $CWD/06_const-chars.patch -patch -p1 -i $CWD/07_gcc4.3.patch -patch -p1 -i $CWD/08_fix_const_conversion.patch -patch -p1 -i $CWD/09_deprecated_SigC.patch -patch -p1 -i $CWD/10_workhelper-buttonbox.patch +# Thanks to Debian for the patches +patch -p1 -i $CWD/patches/03_multidir.patch +patch -p1 -i $CWD/patches/05_gcc4.1.patch +patch -p1 -i $CWD/patches/06_const-chars.patch +patch -p1 -i $CWD/patches/07_gcc4.3.patch +patch -p1 -i $CWD/patches/08_fix_const_conversion.patch +patch -p1 -i $CWD/patches/09_deprecated_SigC.patch +patch -p1 -i $CWD/patches/10_workhelper-buttonbox.patch +patch -p1 -i $CWD/patches/11_explicit-linkage.patch CFLAGS="$SLKCFLAGS" \ CXXFLAGS="$SLKCFLAGS" \ @@ -88,12 +100,13 @@ for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; r mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION cp -a \ - ChangeLog COPYING COPYING.BULGARIAN README TODO THANKS \ + ChangeLog ChangeLog.html COPYING COPYING.BULGARIAN README TODO THANKS \ $PKG/usr/doc/$PRGNAM-$VERSION cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild -mkdir -p $PKG/usr/share/applications +mkdir -p $PKG/usr/share/{applications,pixmaps} cp $CWD/$PRGNAM.desktop $PKG/usr/share/applications +cp pixmaps/gbgoffice-icon.png $PKG/usr/share/pixmaps/gbgoffice.png mkdir -p $PKG/install cat $CWD/slack-desc > $PKG/install/slack-desc diff --git a/office/gbgoffice/gbgoffice.desktop b/office/gbgoffice/gbgoffice.desktop index bde7b0e52951..6dcacae0abb3 100644 --- a/office/gbgoffice/gbgoffice.desktop +++ b/office/gbgoffice/gbgoffice.desktop @@ -1,11 +1,11 @@ [Desktop Entry] Version=1.0 Type=Application -Name=GBGOffice +Name=Gbgoffice Name[bg]=ГБГОфис GenericName=BG Office Assistant GenericName[bg]=БГ Офис помощник Exec=gbgoffice -Icon=/usr/share/bgoffice/gbgoffice-icon.png +Icon=gbgoffice.png Categories=Office; Terminal=false diff --git a/office/gbgoffice/gbgoffice.info b/office/gbgoffice/gbgoffice.info index e111db3a443c..464b8be9ad28 100644 --- a/office/gbgoffice/gbgoffice.info +++ b/office/gbgoffice/gbgoffice.info @@ -1,10 +1,10 @@ PRGNAM="gbgoffice" VERSION="1.4" HOMEPAGE="http://gbgoffice.info/" -DOWNLOAD="http://openfmi.net/frs/download.php/341/gbgoffice-1.4.tar.gz" -MD5SUM="d747bc284f90317fcf4256891a9df381" +DOWNLOAD="http://ftp.debian.org/debian/pool/main/g/gbgoffice/gbgoffice_1.4.orig.tar.gz" +MD5SUM="c99299f0bae7977e1e512dffd5d90c33" DOWNLOAD_x86_64="" MD5SUM_x86_64="" -REQUIRES="full-pack gtkmm" +REQUIRES="libsigc++ gtkmm" MAINTAINER="Petar Petrov" EMAIL="ppetrov@paju.oulu.fi" diff --git a/office/gbgoffice/patches/03_multidir.patch b/office/gbgoffice/patches/03_multidir.patch new file mode 100644 index 000000000000..800c52863d7f --- /dev/null +++ b/office/gbgoffice/patches/03_multidir.patch @@ -0,0 +1,589 @@ +# Author: Damyan Ivanov <dmn@debian.org> +# Description: add support to multiple dictionary directories +# stolen from upstream multidir branch + +--- a/configure.in ++++ b/configure.in +@@ -26,10 +26,13 @@ AC_ARG_ENABLE(light-version, + echo "Light version will be compiled..." + AC_DEFINE([USE_LIGHT],[],[enable light version])],) + +-AC_ARG_ENABLE(dictionary-dir, +-[ --enable-dictionary-dir search for dictionaries only in /usr/local/share/bgoffice dir],[ +- echo "Dictionary lookup enabled..." +- AC_DEFINE([USE_USER_LOCAL],[],[dictionary lookup])],) ++AC_ARG_ENABLE(dictionary-dirs, ++[ --enable-dictionary-dirs=DIRS List default dictiopnary directories (Use colon to delimit entries. Default is /usr/local/share/bgoffice)], ++[ ++ test -z "$enableval" && echo "--enable-dictionary-dirs requires an argument" && exit 1 ++ AC_DEFINE_UNQUOTED([DICT_DIRS],["$enableval"],[default dictionary directories]) ++ echo "Default dictionary directories set to $enableval" ++],) + + AC_ARG_ENABLE(trayicon, + [ --disable-trayicon disable trayicon support],[ +--- a/src/defaults.h ++++ b/src/defaults.h +@@ -24,6 +24,7 @@ + + #include "config.h" + ++#define DICT_DIR_DELIMITER ':' + + #ifdef DATA_DIR_CONFIG + static const char FILES_DIR[] = DATA_DIR_CONFIG; +@@ -32,8 +33,8 @@ static const char FILES_DIR[] = "/usr/lo + #endif + + +-#ifdef USE_USER_LOCAL +-static const char DICT_DIR[] = "/usr/local/share/bgoffice/"; ++#ifdef DICT_DIRS ++static const char DICT_DIR[] = DICT_DIRS; + #else + static const char DICT_DIR[] = DATA_DIR_CONFIG; + #endif +--- a/src/dictgui.cpp ++++ b/src/dictgui.cpp +@@ -38,7 +38,7 @@ + extern Properties *cfg; + extern bool lang; + +-DictGui::DictGui(int argc, char **argv, const char *dir) ++DictGui::DictGui(int argc, char **argv, const vector<string> dirs) + #ifndef ENABLE_LIGHT_VERSION + : spacer(" "), + add_to_history(true), +@@ -48,7 +48,8 @@ DictGui::DictGui(int argc, char **argv, + #endif + + { +- dataDir = dir; ++ dataDirs = dirs; ++ + use_tray = cfg->getBool("UseTray", true); + use_tray_close = cfg->getBool("UseTrayClose", false); + tray_hide_os = cfg->getBool("TrayHideOnStart", false); +@@ -66,7 +67,7 @@ DictGui::DictGui(int argc, char **argv, + + splash->set_step(0.2); + #endif +- dict = new TranslatorManager((char*) dataDir); ++ dict = new TranslatorManager(dataDirs); + if (!dict->init()) { + #ifndef ENABLE_LIGHT_VERSION + delete splash; +--- a/src/dictgui.h ++++ b/src/dictgui.h +@@ -38,7 +38,7 @@ class DictGui : public GbgofficeTools + { + + public: +- DictGui(int argc, char **argv, const char *dir); ++ DictGui(int argc, char **argv, const vector<string> dirs); + virtual ~DictGui(); + + void run(); +@@ -58,7 +58,7 @@ public: + + protected: + // our data directory +- const char *dataDir; ++ vector<string> dataDirs; + + // number of words in list (treeview widget) + // this will not be taken from cfg, for faster access +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -27,16 +27,80 @@ + #include <cstring> + #include <getopt.h> + #include <gtkmm/main.h> ++ + using namespace std; + + extern char *optarg; + Properties *cfg; + bool lang = false; ++vector<string> defaultDictDirs; ++vector<string> userDictDirs; ++vector<string> dictDirs; ++ ++vector<string> splitString(const string path, char delimiter) ++{ ++ vector<string> result; ++ string str = path; ++ size_t p; ++ ++ if (str.length()) { ++ do { ++ p = str.find(delimiter); ++ if (p != str.npos) { ++ if (p != 0) { ++ result.push_back(str.substr(0, p)); ++ } ++ str = str.substr(p + 1); ++ } else { ++ if (str.length()) { ++ result.push_back(str); ++ } ++ break; ++ } ++ } while (p != str.npos); ++ } ++ ++ return result; ++} ++ ++void prepareDictDirs() ++{ ++ userDictDirs = splitString(cfg->getString("DataDir", ""), DICT_DIR_DELIMITER); ++// std::cout << (cfg->getString("DataDir", DICT_DIR)) << std::endl; ++ defaultDictDirs = splitString( DICT_DIR, DICT_DIR_DELIMITER ); + ++ // start with directories from user configuration ++ ++ if(userDictDirs.size() == 0) { ++ dictDirs = defaultDictDirs; ++ } else { ++ dictDirs = userDictDirs; ++ } ++ ++/* ++ // then add non-duplicating default directories ++ defaultDictDirs = splitString( DICT_DIR, DICT_DIR_DELIMITER ); ++ ++ for( size_t i = 0; i < defaultDictDirs.size(); i++) { ++ string candidate = defaultDictDirs[i]; ++ bool found = false; ++ ++ for( size_t j = 0; j < dictDirs.size(); j++ ) { ++ if( candidate == dictDirs[j] ) { ++ found = true; ++ break; ++ } ++ } ++ ++ if( !found ) { ++ dictDirs.push_back(candidate); ++ } ++ } */ ++} + + int main(int argc, char **argv) + { +- char *env, *path, *dataDir; ++ char *env, *path; + int ch; + + +@@ -55,13 +119,8 @@ int main(int argc, char **argv) + * with some modifications + */ + cfg = new Properties(getenv("HOME"), CONF_FILENAME); +- path = cfg->getString("DataDir", DICT_DIR); +- dataDir = new char[strlen(path) + 2]; +- strcpy(dataDir, path); +- if ((dataDir[0] != '\0') && (dataDir[strlen(dataDir) - 1] != '/')) { +- strcat(dataDir, "/"); +- } +- ++ prepareDictDirs(); ++ + + /* parsing command line options */ + while ((ch = getopt_long(argc, argv, "dhl:v", longopts, NULL)) != -1) { +@@ -71,7 +130,7 @@ int main(int argc, char **argv) + return 0; + + case 'd': +- cout << dataDir << endl; ++ cout << dictDirs[0] << endl; + return 0; + + case 'l': +@@ -125,7 +184,7 @@ int main(int argc, char **argv) + Gtk::Main kit(argc, argv); + + // gui init +- DictGui maindict(argc, argv, dataDir); ++ DictGui maindict(argc, argv, dictDirs); + + #if !defined(ENABLE_LIGHT_VERSION) && !defined(DISABLE_TRAY) + if (use_tray) { +@@ -140,3 +199,4 @@ int main(int argc, char **argv) + return 0; + } + ++// vi: set tabstop=8 noexpandtab softtabstop=8 shiftwidth=8 : +--- a/src/properties.cpp ++++ b/src/properties.cpp +@@ -23,6 +23,10 @@ + #include <stdio.h> + #include <string.h> + ++#ifdef DEBUG ++#include <iostream> ++#endif ++ + #include "properties.h" + + +@@ -39,21 +43,41 @@ const int Properties::MAX_LINE_LEN = 10 + const int Properties::MAX_KEY_LEN = 128; + + +-Properties::Properties(const char *path, const char *file, const char *suffix) { ++Properties::Properties(const char *file_path, const char *file, const char *suffix) { ++ char *p; ++ + // Allocate memory + buf = new char[MAX_LINE_LEN]; + sbuf = new char[MAX_LINE_LEN]; + key = new char[MAX_KEY_LEN]; +- fileName = new char[strlen(path) + strlen(file) + 2]; +- backupFileName = new char[strlen(path) + strlen(file) + strlen(suffix) + 2]; ++ ++ ++ fileName = new char[strlen(file_path) + strlen(file) + 2]; ++ backupFileName = new char[strlen(file_path) + strlen(file) + strlen(suffix) + 2]; + // Copy file names in local variables +- strcpy(fileName, path); +- if ((path[0] != '\0') && (path[strlen(path) - 1] != '/')) { ++ strcpy(fileName, file_path); ++ if (strlen(file)) { + strcat(fileName, "/"); ++ strcat(fileName, file); + } +- strcat(fileName, file); + strcpy(backupFileName, fileName); + strcat(backupFileName, suffix); ++ ++ // Find directory name ++#ifdef DEBUG ++ std::cerr << "Properties:: parsing fileName '"<< fileName <<"'\n"; ++#endif ++ p = strrchr( fileName, '/' ); ++ if (p) { ++ directory = new char[ p - fileName + 2 ]; ++ strncpy( directory, fileName, p-fileName + 1); // include the slash ++ directory[p-fileName+1] = '\0'; // terminate ++ } else { ++ directory = "./"; ++ } ++#ifdef DEBUG ++ std::cerr << "Properties:: directory is '"<<directory<<"'\n"; ++#endif + } + + +@@ -63,6 +87,7 @@ Properties::~Properties() { + delete [] key; + delete [] fileName; + delete [] backupFileName; ++ delete [] directory; + } + + +@@ -186,3 +211,5 @@ bool Properties::setInt(const char *prop + bool Properties::setBool(const char *property, const bool value) { + return setString(property, (value ? "true" : "false")); + } ++ ++// vi: set noexpandtab softtabstop=0 tabstop=8 shiftwidth=8 : +--- a/src/properties.h ++++ b/src/properties.h +@@ -30,7 +30,7 @@ + class Properties { + + public: +- Properties(const char *path, const char *file, const char *suffix = "~"); ++ Properties(const char *file_path, const char *file = "", const char *suffix = "~"); + ~Properties(); + char *getString(const char *property, const char *defaultValue = ""); + int getInt(const char *property, const int defaultValue = 0); +@@ -39,6 +39,7 @@ public: + bool setString(const char *property, const char *value); + bool setInt(const char *property, const int value); + bool setBool(const char *property, const bool value); ++ char *getDirectory() { return directory; }; + + private: + static const int MAX_LINE_LEN; +@@ -48,7 +49,10 @@ private: + char *key; + char *fileName; + char *backupFileName; ++ char *directory; + + }; + + #endif ++ ++// vi: set noexpandtab softtabstop=0 tabstop=8 shiftwidth=8 : +--- a/src/translator.cpp ++++ b/src/translator.cpp +@@ -23,6 +23,10 @@ + #include <string.h> + #include <ctype.h> + ++#ifdef DEBUG ++#include <iostream.h> ++#endif ++ + #include "database.h" + #include "translator.h" + +@@ -111,9 +115,15 @@ Translator::~Translator() { + bool Translator::init(const int type, const char *fileName, const long fixedLastWordPointer) { + // Check input data + if ((type != EN_BG) && (type != BG_EN)) { ++#ifdef DEBUG ++ std::cerr << "Translator::init: failure 1\n"; ++#endif + return false; + } + if ((dictionaryType != DUAL) && (type != dictionaryType)) { ++#ifdef DEBUG ++ std::cerr << "Translator::init: failure 2\n"; ++#endif + return false; + } + // Init database +@@ -121,9 +131,19 @@ bool Translator::init(const int type, co + if (type == EN_BG) { + dictEnBg = new Database(); + ret = dictEnBg->init(fileName, fixedLastWordPointer); ++#ifdef DEBUG ++ if( !ret ) { ++ std::cerr << "Translator::init: failure 3 " << fileName << "\n"; ++ } ++#endif + } else { + dictBgEn = new Database(); + ret = dictBgEn->init(fileName, fixedLastWordPointer); ++#ifdef DEBUG ++ if( !ret ) { ++ std::cerr << "Translator::init: failure 4 " << fileName << "\n"; ++ } ++#endif + } + // Set current dictionary + // If it is dual, en-bg is set as default +@@ -669,3 +689,5 @@ char *Translator::extractText(const char + dataBuffer[j] = '\0'; + return dataBuffer; + } ++ ++// vi: set noexpandtab softtabstop=0 tabstop=8 shiftwidth=8 : +--- a/src/translator_manager.cpp ++++ b/src/translator_manager.cpp +@@ -46,8 +46,8 @@ using namespace std; + */ + + +-TranslatorManager::TranslatorManager(char *pDataDir) { +- dataDir = pDataDir; ++TranslatorManager::TranslatorManager(const vector<string> dirs) { ++ dataDirs = dirs; + } + + +@@ -63,17 +63,17 @@ bool TranslatorManager::init(const bool + char *lang = getenv("LANG"); + bool isBG = (!ignoreLANG) && (lang != NULL) && (lang[0] == 'b') && (lang[1] == 'g'); + // Load Dictionaries +- vector<string> dict = findFiles(dataDir, ".dict"); ++ vector<string> dict = findFiles(dataDirs, ".dict"); + if (dict.size() == 0) { +- cerr << "TranslatorManager::init - There is no dictionary files in directory: " << dataDir << "\n"; ++ cerr << "TranslatorManager::init - There are no dictionary files. Run with -d to see where are the dictionary directories\n" << std::endl; + return false; + } + for (unsigned int i = 0; i < dict.size(); i++) { +- Properties *prop = new Properties(dataDir, dict[i].c_str()); ++ Properties *prop = new Properties(dict[i].c_str()); + struct Dictionary d; +- d.file = dict[i]; ++ d.fileName = dict[i]; + d.version = string(prop->getString("version")); +- d.icon = string(dataDir) + prop->getString("icon"); ++ d.icon = string(prop->getDirectory()) + prop->getString("icon"); + d.name = string(prop->getString(isBG ? "name.bg" : "name")); + dictionaries.push_back(d); + string type = string(prop->getString("type")); +@@ -81,14 +81,26 @@ bool TranslatorManager::init(const bool + bool isDataOk = true; + if (type.compare("dual") == 0) { + tr = new Translator(tr->DUAL); +- isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(dataDir) + prop->getString("data.en")).c_str()); +- isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(dataDir) + prop->getString("data.bg")).c_str()); ++ isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(prop->getDirectory()) + prop->getString("data.en")).c_str()); ++#ifdef DEBUG ++ cerr << 1 << isDataOk << "\n"; ++#endif ++ isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(prop->getDirectory()) + prop->getString("data.bg")).c_str()); ++#ifdef DEBUG ++ cerr << 2 << isDataOk << "\n"; ++#endif + } else if (type.compare("en") == 0) { + tr = new Translator(tr->EN_BG); +- isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(dataDir) + prop->getString("data")).c_str()); ++ isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(prop->getDirectory()) + prop->getString("data")).c_str()); ++#ifdef DEBUG ++ cerr << 3 << isDataOk << prop->getDirectory() << "+" << prop->getString("data") << "\n"; ++#endif + } else if (type.compare("bg") == 0) { + tr = new Translator(tr->BG_EN); +- isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(dataDir) + prop->getString("data")).c_str()); ++ isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(prop->getDirectory()) + prop->getString("data")).c_str()); ++#ifdef DEBUG ++ cerr << 4 << isDataOk << "\n"; ++#endif + } else { + cerr << "TranslatorManager::init - Wrong description file: " << dict[i] << "\n"; + return false; +@@ -104,11 +116,11 @@ bool TranslatorManager::init(const bool + currentTranslator = translators[0]; + + // Load TestDictionaries +- vector<string> test = findFiles(dataDir, ".test"); ++ vector<string> test = findFiles(dataDirs, ".test"); + for (unsigned int i = 0; i < test.size(); i++) { +- Properties *prop = new Properties(dataDir, test[i].c_str()); ++ Properties *prop = new Properties(test[i].c_str()); + struct TestDictionary td; +- td.file = test[i]; ++ td.fileName = test[i]; + td.name = string(prop->getString(isBG ? "name.bg" : "name")); + testDictionaries.push_back(td); + delete prop; +@@ -152,22 +164,22 @@ TestDictionary TranslatorManager::getTes + + + Translator *TranslatorManager::getTestDictionaryObject(const int index, const int level) { +- Properties *prop = new Properties(dataDir, testDictionaries[index].file.c_str()); ++ Properties *prop = new Properties(testDictionaries[index].fileName.c_str()); + string type = string(prop->getString("type")); + Translator *tr; + bool isDataOk = true; + if (type.compare("en") == 0) { + tr = new Translator(tr->EN_BG); +- isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(dataDir) + prop->getString("data")).c_str()); ++ isDataOk = isDataOk && tr->init(tr->EN_BG, string(string(prop->getDirectory()) + prop->getString("data")).c_str()); + } else if (type.compare("bg") == 0) { + tr = new Translator(tr->BG_EN); +- isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(dataDir) + prop->getString("data")).c_str()); ++ isDataOk = isDataOk && tr->init(tr->BG_EN, string(string(prop->getDirectory()) + prop->getString("data")).c_str()); + } else { +- cerr << "TranslatorManager::getTestDictionaryObject - Wrong description file: " << testDictionaries[index].file << "\n"; ++ cerr << "TranslatorManager::getTestDictionaryObject - Wrong description file: " << testDictionaries[index].fileName << "\n"; + return false; + } + if (!isDataOk) { +- cerr << "TranslatorManager::getTestDictionaryObject - Problem initialazing dictionary: " << testDictionaries[index].file << "\n"; ++ cerr << "TranslatorManager::getTestDictionaryObject - Problem initialazing dictionary: " << testDictionaries[index].fileName << "\n"; + return false; + } + char c[16]; +@@ -309,30 +321,37 @@ void TranslatorManager::setAdvancedSearc + } + } + +- +-vector<string> TranslatorManager::findFiles(const char *dir, const char *extension) { ++vector<string> TranslatorManager::findFiles(const vector<string> dirs, const char *extension) { + int l = strlen(extension); + vector<string> result; + DIR *d; + struct dirent *e; ++ size_t i; ++ const char *i_dir; + +- if ((d = opendir(dir)) == NULL) { +- cerr << "TranslatorManager::findFiles - Unable to open directory: " << dir << "\n"; +- return result; +- } ++ for (i = 0; i < dirs.size(); i++) { ++ i_dir = dirs[i].c_str(); + +- while ((e = readdir(d)) != NULL) { +- string fn(e->d_name); +- size_t p = fn.rfind(extension); +- if ((p != string::npos) && (p == fn.size() - l)) { +- result.push_back(fn); ++ if ((d = opendir(i_dir)) == NULL) { ++ cerr << "TranslatorManager::findFiles - Unable to open directory: " << i_dir << "\n"; ++ continue; + } +- } + +- if (closedir(d) != 0) { +- cerr << "TranslatorManager::findFiles - Unable to close directory: " << dir << "\n"; ++ while ((e = readdir(d)) != NULL) { ++ string fn(e->d_name); ++ size_t p = fn.rfind(extension); ++ if ((p != string::npos) && (p == fn.size() - l)) { ++ result.push_back(string(i_dir) + '/' + string(fn)); ++ } ++ } ++ ++ if (closedir(d) != 0) { ++ cerr << "TranslatorManager::findFiles - Unable to close directory: " << i_dir << "\n"; ++ } + } + + sort(result.begin(), result.end()); + return result; + } ++ ++// vi: set noexpandtab softtabstop=0 tabstop=8 shiftwidth=8 : +--- a/src/translator_manager.h ++++ b/src/translator_manager.h +@@ -36,14 +36,14 @@ using namespace std; + + + struct Dictionary { +- string file; ++ string fileName; + string name; + string icon; + string version; + }; + + struct TestDictionary { +- string file; ++ string fileName; + string name; + }; + +@@ -51,7 +51,7 @@ struct TestDictionary { + class TranslatorManager { + + public: +- TranslatorManager(char *pDataDir); ++ TranslatorManager(const vector<string> dataDirs); + ~TranslatorManager(); + bool init(const bool ignoreLANG = false); + +@@ -92,7 +92,7 @@ public: + + + private: +- char *dataDir; ++ vector<string> dataDirs; + + vector<Dictionary> dictionaries; + vector<TestDictionary> testDictionaries; +@@ -101,8 +101,10 @@ private: + Translator *currentTranslator; + int currentDict; + +- vector<string> findFiles(const char *dir, const char *extension); ++ vector<string> findFiles(const vector<string> dirs, const char *extension); + + }; + + #endif ++ ++// vi: set noexpandtab softtabstop=0 tabstop=8 shiftwidth=8 : diff --git a/office/gbgoffice/patches/04_fix_fsf_address.patch b/office/gbgoffice/patches/04_fix_fsf_address.patch new file mode 100644 index 000000000000..1875990644df --- /dev/null +++ b/office/gbgoffice/patches/04_fix_fsf_address.patch @@ -0,0 +1,29 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 04_fix_fsf_address.dpatch by <divanov@creditreform.bg> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: No description. + +@DPATCH@ +--- a/COPYING ++++ b/COPYING +@@ -2,7 +2,7 @@ + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. +- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +--- a/COPYING.BULGARIAN ++++ b/COPYING.BULGARIAN +@@ -28,7 +28,7 @@ understand the GNU GPL better. + + + 1989, 1991 , . +- 59 , 330 MA 02111-1307 ++ 51 , , , MA 02110-1301, + + , . + diff --git a/office/gbgoffice/patches/05_gcc4.1.patch b/office/gbgoffice/patches/05_gcc4.1.patch new file mode 100644 index 000000000000..bf22f6453a92 --- /dev/null +++ b/office/gbgoffice/patches/05_gcc4.1.patch @@ -0,0 +1,14 @@ +# Author: Damyan Ivanov <dmn@debian.org> +# Description: fix methid declaration +# GCC 4.1 brafs if it is fully qualified +--- a/src/trayicon.h ++++ b/src/trayicon.h +@@ -38,7 +38,7 @@ public: + TrayIcon(DictGui *win); + ~TrayIcon(); + +- Gtk::Window *TrayIcon::getWindow(); ++ Gtk::Window *getWindow(); + + private: + virtual bool on_button_press(GdkEventButton* event); diff --git a/office/gbgoffice/patches/06_const-chars.patch b/office/gbgoffice/patches/06_const-chars.patch new file mode 100644 index 000000000000..419a9ff4ae72 --- /dev/null +++ b/office/gbgoffice/patches/06_const-chars.patch @@ -0,0 +1,289 @@ +# Author: Damyan Ivanov <dmn@debian.org> +# Description: declare inline strings as constants +# Modern GCC (rightfully) complain otherwise +--- a/src/language_tools.h ++++ b/src/language_tools.h +@@ -27,19 +27,19 @@ + #define LT_(x) true == lang ? Glib::convert(x[1], "UTF-8", "CP1251"): x[0] + + +-static char *HELP_MESSAGE[] = { ++static const char *HELP_MESSAGE[] = { + "Type a word (bulgarian or english) in entry box above", + " ( ) -" + }; + + +-static char *WELLCOME_MESSAGE[] = { ++static const char *WELLCOME_MESSAGE[] = { + "Wellcome to GTK BG Office!", + " GTK . !" + }; + + +-static char *ABOUT_MESSAGE[] = { ++static const char *ABOUT_MESSAGE[] = { + "GTK BG Office assistant - version 1.4 \n" + "Official webpage - http://gbgoffice.info\n\n" + "(C) 2004-2006 Miroslav Yordanov <mironcho@linux-bg.org>\n" +@@ -52,7 +52,7 @@ static char *ABOUT_MESSAGE[] = { + }; + + +-static char *CONFIG_ERROR[] = { ++static const char *CONFIG_ERROR[] = { + "The configuration could not be initialized\n" + "This is fatal error and gbgoffice now will exit!", + +@@ -61,7 +61,7 @@ static char *CONFIG_ERROR[] = { + }; + + +-static char *ERROR_INIT_TRAYICON[] = { ++static const char *ERROR_INIT_TRAYICON[] = { + "Error initializing trayicon module.\n" + "This is fatal error and gbgoffice now will exit!", + +@@ -70,7 +70,7 @@ static char *ERROR_INIT_TRAYICON[] = { + }; + + +-static char *DATA_MISSING[] = { ++static const char *DATA_MISSING[] = { + "Dicionary files are missing.\n" + "Please check that you have installed them\n" + "and if they are missing, visit\n" +@@ -86,7 +86,7 @@ static char *DATA_MISSING[] = { + }; + + +-static char *DATA_MISSING_FEDORA[] = { ++static const char *DATA_MISSING_FEDORA[] = { + "Dicionary files are missing.\n" + "Please check that you have installed them\n" + "and if they are missing, please use the supplied \n" +@@ -105,190 +105,190 @@ static char *DATA_MISSING_FEDORA[] = { + + + +-static char *GUI_CURRENT_DICT[] = { ++static const char *GUI_CURRENT_DICT[] = { + "Current dictionary - ", + " - " + }; + + +-static char *GUI_NEXT_WORDS[] = { ++static const char *GUI_NEXT_WORDS[] = { + "next words", + " " + }; + + +-static char *GUI_MENU_FILE[] = { ++static const char *GUI_MENU_FILE[] = { + "_File", + "_" + }; + + +-static char *GUI_MENU_EDIT[] = { ++static const char *GUI_MENU_EDIT[] = { + "_Edit", + "_" + }; + + +-static char *GUI_MENU_DICTS[] = { ++static const char *GUI_MENU_DICTS[] = { + "_Dictionaries", + "_" + }; + + +-static char *GUI_MENU_SETTINGS[] = { ++static const char *GUI_MENU_SETTINGS[] = { + "_Settings", + "_" + }; + + +-static char *GUI_MENU_HELP[] = { ++static const char *GUI_MENU_HELP[] = { + "_Help", + "_" + }; + + +-static char *GUI_VIEW_HISTORY[] = { ++static const char *GUI_VIEW_HISTORY[] = { + "View history", + " " + }; + + +-static char *GUI_PREFS_NUM_WORDS[] = { ++static const char *GUI_PREFS_NUM_WORDS[] = { + " Number of words in list", + " " + }; + + +-static char *GUI_PREFS_USE_CLIPBOARD[] = { ++static const char *GUI_PREFS_USE_CLIPBOARD[] = { + " Watch clipboard for new words", + " " + }; + + +-static char *GUI_PREFS_TAB_GENERAL[] = { ++static const char *GUI_PREFS_TAB_GENERAL[] = { + "General", + "" + }; + + +-static char *GUI_PREFS_TAB_TRAY[] = { ++static const char *GUI_PREFS_TAB_TRAY[] = { + "Trayicon", + "Trayicon" + }; + + +-static char *GUI_PREFS_TAB_TRAY_HELP[] = { ++static const char *GUI_PREFS_TAB_TRAY_HELP[] = { + "<b>You must restart gbgoffice \nbefore these settings take effect</b>", + "<b> gbgoffice \n </b>" + }; + + +-static char *GUI_PREFS_USE_TRAYICON[] = { ++static const char *GUI_PREFS_USE_TRAYICON[] = { + " Use trayicon", + " trayicon" + }; + + +-static char *GUI_PREFS_USE_TRAYICON_CLOSE[] = { ++static const char *GUI_PREFS_USE_TRAYICON_CLOSE[] = { + " Closing main window,\n quits application", + " ,\n " + }; + +-static char *GUI_PREFS_TRAYICON_HIDE_ON_START[] = { ++static const char *GUI_PREFS_TRAYICON_HIDE_ON_START[] = { + " Hide main window on startup", + " " + }; + + +-static char *GUI_PREFS_USE_WH[] = { ++static const char *GUI_PREFS_USE_WH[] = { + " Use helper", + " " + }; + + +-static char *GUI_PREFS_WH_SECONDS[] = { ++static const char *GUI_PREFS_WH_SECONDS[] = { + " time for showing helper\n (in seconds)", + " \n ( )" + }; + + +-static char *GUI_EXAM_MENU[] = { ++static const char *GUI_EXAM_MENU[] = { + "Make a test", + " " + }; + + +-static char *GUI_EXAM_CORRECT[] = { ++static const char *GUI_EXAM_CORRECT[] = { + "correct", + "" + }; + +-static char *GUI_EXAM_INCORRECT[] = { ++static const char *GUI_EXAM_INCORRECT[] = { + "incorrect", + "" + }; + +-static char *GUI_EXAM_NEWTEST[] = { ++static const char *GUI_EXAM_NEWTEST[] = { + "Press button \"New\" for new test.", + " \"\" ." + }; + +-static char *GUI_EXAM_NEW_LEVEL1[] = { ++static const char *GUI_EXAM_NEW_LEVEL1[] = { + "Novice", + "" + }; + +-static char *GUI_EXAM_NEW_LEVEL2[] = { ++static const char *GUI_EXAM_NEW_LEVEL2[] = { + "Beginner", + "" + }; + +-static char *GUI_EXAM_NEW_LEVEL3[] = { ++static const char *GUI_EXAM_NEW_LEVEL3[] = { + "Intermediate", + "" + }; + +-static char *GUI_EXAM_NEW_LEVEL4[] = { ++static const char *GUI_EXAM_NEW_LEVEL4[] = { + "Specialist", + "" + }; + +-static char *GUI_EXAM_NEW_LEVEL5[] = { ++static const char *GUI_EXAM_NEW_LEVEL5[] = { + "Expert", + "" + }; + +-static char *GUI_EXAM_TRANSLATION[] = { ++static const char *GUI_EXAM_TRANSLATION[] = { + "Translation: ", + ": " + }; + +-static char *GUI_EXAM_DIFFICULTY[] = { ++static const char *GUI_EXAM_DIFFICULTY[] = { + "Difficulty: ", + ": " + }; + +-static char *GUI_EXAM_NUMTEST[] = { ++static const char *GUI_EXAM_NUMTEST[] = { + "Test (0 = random): ", + " (0 = ): " + }; + +-static char *GUI_EXAM_NUMQUEST[] = { ++static const char *GUI_EXAM_NUMQUEST[] = { + "Num of questions: ", + " : " + }; + +-static char *GUI_EXAM_ENDOFTEST[] = { ++static const char *GUI_EXAM_ENDOFTEST[] = { + "End of test.", + " ." + }; + +-static char *GUI_EXAM_TESTNOTSTARTED[] = { ++static const char *GUI_EXAM_TESTNOTSTARTED[] = { + "Test not started.", + " ." + }; + +-static char *GUI_EXAM_CORRECT_ANSWERS[] = { ++static const char *GUI_EXAM_CORRECT_ANSWERS[] = { + "correct", + "" + }; diff --git a/office/gbgoffice/patches/07_gcc4.3.patch b/office/gbgoffice/patches/07_gcc4.3.patch new file mode 100644 index 000000000000..8b620cd6235a --- /dev/null +++ b/office/gbgoffice/patches/07_gcc4.3.patch @@ -0,0 +1,14 @@ +# Author: Damyan Ivanov <dmn@debian.org> +# Description: include the right header file +# GCC 4.3 has stricter rules about inclusion propagation +--- a/src/translator_manager.cpp ++++ b/src/translator_manager.cpp +@@ -22,7 +22,7 @@ + + #include <sys/types.h> + #include <dirent.h> +-#include <string> ++#include <cstring> + #include <iostream> + #include <algorithm> + diff --git a/office/gbgoffice/patches/08_fix_const_conversion.patch b/office/gbgoffice/patches/08_fix_const_conversion.patch new file mode 100644 index 000000000000..0aa6c54fcf23 --- /dev/null +++ b/office/gbgoffice/patches/08_fix_const_conversion.patch @@ -0,0 +1,17 @@ +# Description: Since a constant is passed into strchr(), pu must also be const +# to keep the compiler from generating an error. +# Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gbgoffice/+bug/445624 +# Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550115 +# +--- a/src/translator.cpp ++++ b/src/translator.cpp +@@ -315,7 +315,8 @@ bool Translator::findWord(const char *wo + + char *Translator::transformResult(const char *result) { + int j, i, m, n, u; +- char *b, *pu; ++ const char *pu; ++ char *b; + char c; + strcpy(dataBuffer2, result); + if ((advancedSearchState) && (advancedSearchHighlight)) { diff --git a/office/gbgoffice/patches/09_deprecated_SigC.patch b/office/gbgoffice/patches/09_deprecated_SigC.patch new file mode 100644 index 000000000000..3b6151c90294 --- /dev/null +++ b/office/gbgoffice/patches/09_deprecated_SigC.patch @@ -0,0 +1,41 @@ +# Description: fix compilation with gcc-4.5 (and corresponding libstdc++) +# Some deprecated typedefs are finaly removed +# Constructors need not be explicitly named +# Author: George Danchev <danchev@debian.org> +# Forwarded: no +# Debian-Bug: #564991 +--- a/src/dictgui.cpp ++++ b/src/dictgui.cpp +@@ -63,7 +63,7 @@ DictGui::DictGui(int argc, char **argv, + splash->show_now(); // show splash window NOW + splash->flush_queue(); // needed only once + +- history = new History::History(CONF_WORDS_IN_HISTORY, CONF_MAX_WORD_LEN); ++ history = new History(CONF_WORDS_IN_HISTORY, CONF_MAX_WORD_LEN); + + splash->set_step(0.2); + #endif +--- a/src/dictgui.h ++++ b/src/dictgui.h +@@ -147,8 +147,8 @@ protected: + + Glib::RefPtr<Gtk::TextBuffer> tbuf; + +- SigC::Connection con_entry; +- SigC::Connection con_timer; ++ sigc::connection con_entry; ++ sigc::connection con_timer; + + Glib::RefPtr<Gtk::Clipboard> clp; + +--- a/src/workhelper.h ++++ b/src/workhelper.h +@@ -59,7 +59,7 @@ private: + Gtk::TextView textarea; + Gtk::ScrolledWindow scwin; + Gtk::VScrollbar *vs; +- SigC::Connection con_wait; ++ sigc::connection con_wait; + + unsigned int hide_timeout; + unsigned int sizex, sizey; diff --git a/office/gbgoffice/patches/10_workhelper-buttonbox.patch b/office/gbgoffice/patches/10_workhelper-buttonbox.patch new file mode 100644 index 000000000000..d8d77a8deedb --- /dev/null +++ b/office/gbgoffice/patches/10_workhelper-buttonbox.patch @@ -0,0 +1,16 @@ +# Description: fix hba declaration to match get_action_area return type +# Gtk::Dialog 2.18 now defines this as a generic ButtonBox +# Forwarded: no +# Bug-Debian: 577371 +# Author: Damyan Ivanov <dmn@debian.org> +--- a/src/workhelper.cpp ++++ b/src/workhelper.cpp +@@ -39,7 +39,7 @@ WorkHelper::WorkHelper() + //set_resize_mode(Gtk::RESIZE_PARENT); + set_reallocate_redraws(true); + +- Gtk::HButtonBox *hba = get_action_area(); ++ Gtk::ButtonBox *hba = get_action_area(); + + add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + diff --git a/office/gbgoffice/patches/11_explicit-linkage.patch b/office/gbgoffice/patches/11_explicit-linkage.patch new file mode 100644 index 000000000000..5b855a1a8c84 --- /dev/null +++ b/office/gbgoffice/patches/11_explicit-linkage.patch @@ -0,0 +1,29 @@ +# Description: explicitly link against libX11 +# The binary uses its symbols and not linking explicitly causes +# a failure to build with GNU binutils gold +# Author: Bhavani Shankar R <bhavi@ubuntu.com> +# Bug-Debian: http://bugs.debian.org/554373 +# Forwarded: no + +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -33,7 +33,7 @@ noinst_HEADERS = \ + dictgui.h \ + language_tools.h + +-gbgoffice_LDADD = @LIBS@ @GTKMM_LIBS@ ++gbgoffice_LDADD = @LIBS@ @GTKMM_LIBS@ -lX11 + + AM_CXXFLAGS = @GTKMM_CFLAGS@ + AM_CPPFLAGS = -DDATA_DIR_CONFIG=\"$(datadir)/bgoffice/\" @CPPFLAGS@ +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -186,7 +186,7 @@ noinst_HEADERS = \ + dictgui.h \ + language_tools.h + +-gbgoffice_LDADD = @LIBS@ @GTKMM_LIBS@ ++gbgoffice_LDADD = @LIBS@ @GTKMM_LIBS@ -lX11 + AM_CXXFLAGS = @GTKMM_CFLAGS@ + AM_CPPFLAGS = -DDATA_DIR_CONFIG=\"$(datadir)/bgoffice/\" @CPPFLAGS@ + all: config.h diff --git a/office/gbgoffice/slack-desc b/office/gbgoffice/slack-desc index 0792d434a1b2..7181b21f9fae 100644 --- a/office/gbgoffice/slack-desc +++ b/office/gbgoffice/slack-desc @@ -8,12 +8,12 @@ |-----handy-ruler------------------------------------------------------| gbgoffice: gbgoffice (Bgoffice dictionary frontend) gbgoffice: -gbgoffice: gbgoffice provides an easy to use GTK interface for the dictionaries -gbgoffice: from the Bulgarian Office project. -gbgoffice: -gbgoffice: -gbgoffice: -gbgoffice: -gbgoffice: +gbgoffice: The GTK BG Office assistant (Gbgoffice) is part of the Bulgarian +gbgoffice: Office project (Bgoffice). Gbgoffice provides an easy to use GTK+ +gbgoffice: interface for the Bgoffice dictionaries. It supports all five of +gbgoffice: them: 1) Dual Bulgarian English dictionary; 2) Dictionary of +gbgoffice: computer terms; 3) Dialect dictionary; 4) Polytechnical English +gbgoffice: Bulgarian dictionary; 5) Thesaurus; gbgoffice: gbgoffice: Home: http://gbgoffice.info/ +gbgoffice: |