להורדה | תוסף "וורד לאוצריא" - להורדה, לבדיקה, לתיקון ושיפור.
-
@יאיר-דניאל
אם אתה משתמש בספריות הנכונות, ומיישם את הפונקציות כמו שצריך - אתה יכול להגיע רחוק מאוד מאוד.
אבל, חשוב מאוד: אל תתפזר!!!
תכנן משהו אחד, תעשה אותו עד הסוף. גמרת? משתמשים, באגים, תיקונים וכולי.
אבל לדעתי - אתה עושה טעות...
מה האינטרס שלך? נתת כבר חלק יפה מאוד מהפונקציונליות, למה צריך הכל? למה זה טוב? -
זה יכול לעבור אותו בקלות.
אתה נותן לנו תאבון...
אולי יתחילו לעמד ב'אוצריא' - "מהלימוד עד לדפוס", 'עימוד אוטומטי בלחיצת כפתור', ועוד שלל חלומות ופנטזיות - רב טקסט, צורת הדף, וכו'.
אולי מפתחי תוספי וורד בתשלום יתחילו לעשות תוספים בתשלום לאוצריא.
אבל נעצור בזה, שלא תחליט לחסום לנו את ארץ האפשרויות הבלתי מוגבלות. -
@יאיר-דניאל
אם אתה משתמש בספריות הנכונות, ומיישם את הפונקציות כמו שצריך - אתה יכול להגיע רחוק מאוד מאוד.
אבל, חשוב מאוד: אל תתפזר!!!
תכנן משהו אחד, תעשה אותו עד הסוף. גמרת? משתמשים, באגים, תיקונים וכולי.
אבל לדעתי - אתה עושה טעות...
מה האינטרס שלך? נתת כבר חלק יפה מאוד מהפונקציונליות, למה צריך הכל? למה זה טוב?תכנן משהו אחד, תעשה אותו עד הסוף. גמרת? משתמשים, באגים, תיקונים וכולי.
אבל לדעתי - אתה עושה טעות...
מה האינטרס שלך? נתת כבר חלק יפה מאוד מהפונקציונליות, למה צריך הכל? למה זה טוב?אתה צודק בהחלט, אני לא הולך להתמקד בזה - בכ"א לא עכשיו.
אחרי שזה באמת יעבוד טוב - והתגובות היחידות שאקבל יהיו בין - האם אפשר גם שזה ירחף באוויר ל - איפה היית עד היום (ספוייילר: הייתי פה ממש קרוב, קצת אחרי הפינה שם)
אז אולי אתן לקלוד לעבוד על זה בשעות השינה שלי... -
תכנן משהו אחד, תעשה אותו עד הסוף. גמרת? משתמשים, באגים, תיקונים וכולי.
אבל לדעתי - אתה עושה טעות...
מה האינטרס שלך? נתת כבר חלק יפה מאוד מהפונקציונליות, למה צריך הכל? למה זה טוב?אתה צודק בהחלט, אני לא הולך להתמקד בזה - בכ"א לא עכשיו.
אחרי שזה באמת יעבוד טוב - והתגובות היחידות שאקבל יהיו בין - האם אפשר גם שזה ירחף באוויר ל - איפה היית עד היום (ספוייילר: הייתי פה ממש קרוב, קצת אחרי הפינה שם)
אז אולי אתן לקלוד לעבוד על זה בשעות השינה שלי...@יאיר-דניאל מה הגירסה האחרונה (אתה מעדכן בפוסט הראשון כל פעם?)
-
הגירסה האחרונה היא מה שבחנות.
הרגע מעדכן את הפוסט הראשון גם. -
@יאיר-דניאל
אם אתה משתמש בספריות הנכונות, ומיישם את הפונקציות כמו שצריך - אתה יכול להגיע רחוק מאוד מאוד.
אבל, חשוב מאוד: אל תתפזר!!!
תכנן משהו אחד, תעשה אותו עד הסוף. גמרת? משתמשים, באגים, תיקונים וכולי.
אבל לדעתי - אתה עושה טעות...
מה האינטרס שלך? נתת כבר חלק יפה מאוד מהפונקציונליות, למה צריך הכל? למה זה טוב? -
הגירסה האחרונה היא מה שבחנות.
הרגע מעדכן את הפוסט הראשון גם.@יאיר-דניאל
באנדרואיד

-
@י.-פל. איך זה אפשרי?
התוסף בנוי טייפ סקריפט.
זה יצרוך כמויות של קוד רק בשביל הסינכרון של הטקסט עם הגלילה,
יש עוד עשרות דברים שלוקחים כמויות שורות קוד..רק לחשוב על לכתוב את זה עושה לי שחור בעיניים..
-
זה יצרוך כמויות של קוד רק בשביל הסינכרון של הטקסט עם הגלילה,
נו, ואז מה?
תוסף יכול לקבל קבצי קוד מרובים.
למען האמת, בתוסף ש @ע-ה-דכו-ע מתכנן להוציא אי-פעם, יש ערימת קבצים לא מבוטלת... -
-
-
בכל הגירסאות האחרונות הלחצנים של התוסף לא עובדים אצלי בכלל
הגירסה הראשונה לשם שינוי עבדה מעולה -
@יאיר-דניאל אצלי בגדול עובד, למעט פתח בקורא וחפש בספריה
-
-
-
ביקשתי מה-AI ב-VS Code לסייע לי בבניית מהדורה של LibreOffice עם הערות ברצף. הגענו לשלב הסגירה, שבו נדרשת סביבת לינוקס שאינה זמינה לי כרגע.
ביקשתי ממנו לסכם את התהליך שביצע (או תכנן לבצע), ואני מצרף את הסיכום כאן בספוילר.
# מיקום אופקי של הערות ב-LibreOffice Writer - תיעוד שינויים
מי כתב את זה?
אני Cascade, AI coding assistant מבית Cognition. המשתמש ביקש ממני לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות (comments/annotations) אחת אחרי השנייה באותה שורה במקום שכל הערה תתחיל בשורה חדשה.המטרה
ב-LibreOffice Writer, כאשר מספר הערות מקושרות לאותה שורת טקסט, הן מופיעות אחת מתחת לשנייה בסרגל הצד. המטרה היא לאפשר שהערות שמקושרות לאותה שורה יופיעו זו לצד זו (אופקית) – ברצף, ולא כל אחת בשורה חדשה.ארכיטקטורת הקוד
מודול Writer = sw/
כל הקוד הרלוונטי נמצא תחת sw/source/uibase/docvw/קבצים מרכזיים
קובץ תפקיד
sw/source/uibase/docvw/PostItMgr.cxx הקובץ הראשי – ניהול ופריסת כל ההערות
sw/inc/postithelper.hxx מבנה SwLayoutInfo + SwAnnotationItem
לוגיקת הפריסה הנוכחית
LayoutPostIts() ← נקראת בכל רענון
└── LayoutByPage() ← מפרסת הערות לפי עמוד, מונעת חפיפה אנכית
└── SetPosSizePixelRect() ← קובע מיקום וגודל לכל הערה
כיצד נקבע המיקום כיום (לפני השינוי):// Y נקבע לפי מיקום ה-anchor בטקסט
tools::Long nY = mpEditWin->LogicToPixel(
Point(0, pItem->maLayoutInfo.mPosition.Bottom())).Y();// X נקבע תמיד לאותו ערך קבוע
tools::Long nX = mlPageBorder; // ← הבעיה! תמיד אותו X
השינויים שבוצעו
שינוי 1: הוספת שדה mLayoutX למבנה SwAnnotationItem
קובץ: sw/inc/postithelper.hxxשורה: 106
תוכן השינוי:
class SAL_DLLPUBLIC_RTTI SwAnnotationItem final
{
public:
VclPtrsw::annotation::SwAnnotationWin mpPostIt;
bool mbShow;
bool mbFocus;
bool mbPendingLayout;
SwPostItHelper::SwLayoutStatus mLayoutStatus;
SwLayoutInfo maLayoutInfo;
tools::Long mLayoutX = 0; // מיקום אופקי מחושב ← שדה חדש
הסבר: הוספתי שדה חדש mLayoutX למחלקה SwAnnotationItem כדי לשמור את המיקום האופקי המחושב של כל הערה.שינוי 2: שינוי לוגיקת הפריסה ב-PostItMgr.cxx
קובץ: sw/source/uibase/docvw/PostItMgr.cxxפונקציה: LayoutPostIts()
שורות: 990-1139
תוכן השינוי:
לפני השינוי (הקוד המקורי):
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( mlPageBorder , // ← תמיד אותו X Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
אחרי השינוי (הקוד החדש):
// שלב א: קיבוץ הערות לפי Y וחישוב מיקום אופקי
std::map<tools::Long, std::vector<SwAnnotationItem*>> aRowGroups;
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
tools::Long Y = mpEditWin->LogicToPixel(
Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
aRowGroups[Y].push_back(pItem.get());
}
}// שלב ב: לכל קבוצת Y – הקצה X שונה לכל הערה
tools::Long mlPageBorder = 0;
tools::Long mlPageEnd = 0;if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
{
mlPageBorder = mpEditWin->LogicToPixel(Point(pPage->mPageRect.Left(), 0)).X() - nSidebarWidth;
}
else if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
{
mlPageBorder = mpEditWin->LogicToPixel( Point(pPage->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
}for (auto& [nY, aGroup] : aRowGroups)
{
tools::Long nX = mlPageBorder;
for (auto* pItem : aGroup)
{
pItem->mLayoutX = nX;
// חשב את הרוחב של ההערה
bool bCreated = false;
VclPtr<SwAnnotationWin> pPostIt = GetOrCreateAnnotationWindow(*pItem, bCreated);
if (bCreated)
{
aCreatedPostIts.insert(pPostIt);
}tools::Long nTextHeight; if (pPostIt->GetSizePixel().Width() == nSidebarWidth) nTextHeight = pPostIt->GetPostItTextHeight(); else nTextHeight = pPostIt->GuessTextHeightForWidth(nSidebarWidth); tools::Long postItPixelTextHeight = (comphelper::LibreOfficeKit::isActive() ? mpEditWin->LogicToPixel(Point(0, nTextHeight)).Y() : nTextHeight); tools::Long aPostItHeight = (postItPixelTextHeight < pPostIt->GetMinimumSizeWithoutMeta() ? pPostIt->GetMinimumSizeWithoutMeta() : postItPixelTextHeight) + pPostIt->GetMetaHeight(); nX += nSidebarWidth + GetSpaceBetween(); }}
// שלב ג: השתמש ב-mLayoutX בקריאה ל-SetPosSizePixelRect
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( pItem->mLayoutX , // ← מיקום X מחושב Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
הסבר:שלב א: קיבוץ הערות לפי מיקום Y (שורה בטקסט)
שלב ב: לכל קבוצת Y, חישוב מיקום X שונה לכל הערה - הערות מקבלות מיקום X שונה בסדר
שלב ג: שימוש ב-mLayoutX בקריאה ל-SetPosSizePixelRect במקום mlPageBorder קבוע
איך זה עובד
הערות באותה שורה (אותו Y) יופיעו זו לצד זו
המרחק בין הערות נקבע על ידי nSidebarWidth + GetSpaceBetween()
הערות בשורות שונות יופיעו אחת מתחת לשנייה כרגיל
איך לבנות את הקוד
דרישות מקדימותודא שהכלים הבאים מותקנים:
git --version # נדרש git
cmake --version # נדרש cmake 3.15+
make --version # או ninja
gcc --version # gcc 7+ או clang 8+
שלב 1: הורדת הקוד (אם עדיין לא הורד)Clone מלא (גדול! ~4GB)
git clone https://gerrit.libreoffice.org/core libreoffice
cd libreofficeאו: clone רדוד יותר (מהיר יותר לפיתוח)
git clone --depth=1 https://gerrit.libreoffice.org/core libreoffice
cd libreofficeמשיכת submodules
git submodule update --init
שלב 2: הגדרת build
על Linux/macOS:
./autogen.sh
--enable-debug
--disable-online-update
--without-java
--without-help
--without-myspell-dicts
על Windows (MSYS2):
./autogen.sh --enable-debug --disable-online-update
על Windows (WSL - מומלץ):התקנת WSL
wsl --install
בתוך WSL
cd /mnt/e/המצאות/NAU\ WORD/2048/core
./autogen.sh --enable-debug --disable-online-update
שלב 3: בנייה – רק מודול Writer (מהיר!)בנייה ראשונית מלאה (פעם אחת – עלולה לקחת 30-90 דקות)
make -j$(nproc)
לאחר שינויים בקבצי sw בלבד, בנה רק את המודול:
make sw -j$(nproc)
בנייה מהירה עוד יותר עם ninja:
make -j$(nproc) build-nocheck
שלב 4: בדיקת השינוייםהרצת LibreOffice עם השינויים
./instdir/program/swriter
פתח מסמך עם מספר הערות באותה שורה ובדוק שהן מופיעות זו לצד זו
שלב 5: הרצת טסטים
טסטים ספציפיים למודול Writer
make sw_uicheck
טסטים של annotations בלבד
cd sw && make CppunitTest_sw_uiwriter
נקודות תשומת לב
אל תשנה את לוגיקת ה-anchor – רק את חישוב ה-X
שמור על ה-POSTIT_SPACE_BETWEEN הקיים בין הערות
בדוק מקרי קצה: הערה אחת בשורה (צריכה להתנהג כרגיל), הערות בעמודות שונות
שים לב ל-RTL (עברית/ערבית) – המיקום האופקי מתהפך
הקובץ הקריטי הוא PostItMgr.cxx – 90% מהשינוי שם
חפש את הסמן mlPageBorder בקוד – כל מקום שמשתמש בו לציר X הוא מועמד לשינוי
קבצים ששונו
sw/inc/postithelper.hxx - שורה 106 (הוספת שדה mLayoutX)
sw/source/uibase/docvw/PostItMgr.cxx - שורות 990-1139 (שינוי לוגיקת פריסה)
סיכום
השינויים האלו מאפשרים להערות שמקושרות לאותה שורה בטקסט להופיע זו לצד זו במקום אחת מתחת לשנייה. השינוי הוא מינימלי וממוקד, ומשתמש במנגנון הקיים של LibreOffice לפריסת הערות, רק עם לוגיקה שונה לחישוב המיקום האופקי.תאריך: 20 במאי 2026
נכתב על ידי: Cascade (AI coding assistant)
בקשה מקורית: לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות אחת אחרי השנייה באותה שורה -
ביקשתי מה-AI ב-VS Code לסייע לי בבניית מהדורה של LibreOffice עם הערות ברצף. הגענו לשלב הסגירה, שבו נדרשת סביבת לינוקס שאינה זמינה לי כרגע.
ביקשתי ממנו לסכם את התהליך שביצע (או תכנן לבצע), ואני מצרף את הסיכום כאן בספוילר.
# מיקום אופקי של הערות ב-LibreOffice Writer - תיעוד שינויים
מי כתב את זה?
אני Cascade, AI coding assistant מבית Cognition. המשתמש ביקש ממני לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות (comments/annotations) אחת אחרי השנייה באותה שורה במקום שכל הערה תתחיל בשורה חדשה.המטרה
ב-LibreOffice Writer, כאשר מספר הערות מקושרות לאותה שורת טקסט, הן מופיעות אחת מתחת לשנייה בסרגל הצד. המטרה היא לאפשר שהערות שמקושרות לאותה שורה יופיעו זו לצד זו (אופקית) – ברצף, ולא כל אחת בשורה חדשה.ארכיטקטורת הקוד
מודול Writer = sw/
כל הקוד הרלוונטי נמצא תחת sw/source/uibase/docvw/קבצים מרכזיים
קובץ תפקיד
sw/source/uibase/docvw/PostItMgr.cxx הקובץ הראשי – ניהול ופריסת כל ההערות
sw/inc/postithelper.hxx מבנה SwLayoutInfo + SwAnnotationItem
לוגיקת הפריסה הנוכחית
LayoutPostIts() ← נקראת בכל רענון
└── LayoutByPage() ← מפרסת הערות לפי עמוד, מונעת חפיפה אנכית
└── SetPosSizePixelRect() ← קובע מיקום וגודל לכל הערה
כיצד נקבע המיקום כיום (לפני השינוי):// Y נקבע לפי מיקום ה-anchor בטקסט
tools::Long nY = mpEditWin->LogicToPixel(
Point(0, pItem->maLayoutInfo.mPosition.Bottom())).Y();// X נקבע תמיד לאותו ערך קבוע
tools::Long nX = mlPageBorder; // ← הבעיה! תמיד אותו X
השינויים שבוצעו
שינוי 1: הוספת שדה mLayoutX למבנה SwAnnotationItem
קובץ: sw/inc/postithelper.hxxשורה: 106
תוכן השינוי:
class SAL_DLLPUBLIC_RTTI SwAnnotationItem final
{
public:
VclPtrsw::annotation::SwAnnotationWin mpPostIt;
bool mbShow;
bool mbFocus;
bool mbPendingLayout;
SwPostItHelper::SwLayoutStatus mLayoutStatus;
SwLayoutInfo maLayoutInfo;
tools::Long mLayoutX = 0; // מיקום אופקי מחושב ← שדה חדש
הסבר: הוספתי שדה חדש mLayoutX למחלקה SwAnnotationItem כדי לשמור את המיקום האופקי המחושב של כל הערה.שינוי 2: שינוי לוגיקת הפריסה ב-PostItMgr.cxx
קובץ: sw/source/uibase/docvw/PostItMgr.cxxפונקציה: LayoutPostIts()
שורות: 990-1139
תוכן השינוי:
לפני השינוי (הקוד המקורי):
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( mlPageBorder , // ← תמיד אותו X Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
אחרי השינוי (הקוד החדש):
// שלב א: קיבוץ הערות לפי Y וחישוב מיקום אופקי
std::map<tools::Long, std::vector<SwAnnotationItem*>> aRowGroups;
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
tools::Long Y = mpEditWin->LogicToPixel(
Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
aRowGroups[Y].push_back(pItem.get());
}
}// שלב ב: לכל קבוצת Y – הקצה X שונה לכל הערה
tools::Long mlPageBorder = 0;
tools::Long mlPageEnd = 0;if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
{
mlPageBorder = mpEditWin->LogicToPixel(Point(pPage->mPageRect.Left(), 0)).X() - nSidebarWidth;
}
else if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
{
mlPageBorder = mpEditWin->LogicToPixel( Point(pPage->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
}for (auto& [nY, aGroup] : aRowGroups)
{
tools::Long nX = mlPageBorder;
for (auto* pItem : aGroup)
{
pItem->mLayoutX = nX;
// חשב את הרוחב של ההערה
bool bCreated = false;
VclPtr<SwAnnotationWin> pPostIt = GetOrCreateAnnotationWindow(*pItem, bCreated);
if (bCreated)
{
aCreatedPostIts.insert(pPostIt);
}tools::Long nTextHeight; if (pPostIt->GetSizePixel().Width() == nSidebarWidth) nTextHeight = pPostIt->GetPostItTextHeight(); else nTextHeight = pPostIt->GuessTextHeightForWidth(nSidebarWidth); tools::Long postItPixelTextHeight = (comphelper::LibreOfficeKit::isActive() ? mpEditWin->LogicToPixel(Point(0, nTextHeight)).Y() : nTextHeight); tools::Long aPostItHeight = (postItPixelTextHeight < pPostIt->GetMinimumSizeWithoutMeta() ? pPostIt->GetMinimumSizeWithoutMeta() : postItPixelTextHeight) + pPostIt->GetMetaHeight(); nX += nSidebarWidth + GetSpaceBetween(); }}
// שלב ג: השתמש ב-mLayoutX בקריאה ל-SetPosSizePixelRect
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( pItem->mLayoutX , // ← מיקום X מחושב Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
הסבר:שלב א: קיבוץ הערות לפי מיקום Y (שורה בטקסט)
שלב ב: לכל קבוצת Y, חישוב מיקום X שונה לכל הערה - הערות מקבלות מיקום X שונה בסדר
שלב ג: שימוש ב-mLayoutX בקריאה ל-SetPosSizePixelRect במקום mlPageBorder קבוע
איך זה עובד
הערות באותה שורה (אותו Y) יופיעו זו לצד זו
המרחק בין הערות נקבע על ידי nSidebarWidth + GetSpaceBetween()
הערות בשורות שונות יופיעו אחת מתחת לשנייה כרגיל
איך לבנות את הקוד
דרישות מקדימותודא שהכלים הבאים מותקנים:
git --version # נדרש git
cmake --version # נדרש cmake 3.15+
make --version # או ninja
gcc --version # gcc 7+ או clang 8+
שלב 1: הורדת הקוד (אם עדיין לא הורד)Clone מלא (גדול! ~4GB)
git clone https://gerrit.libreoffice.org/core libreoffice
cd libreofficeאו: clone רדוד יותר (מהיר יותר לפיתוח)
git clone --depth=1 https://gerrit.libreoffice.org/core libreoffice
cd libreofficeמשיכת submodules
git submodule update --init
שלב 2: הגדרת build
על Linux/macOS:
./autogen.sh
--enable-debug
--disable-online-update
--without-java
--without-help
--without-myspell-dicts
על Windows (MSYS2):
./autogen.sh --enable-debug --disable-online-update
על Windows (WSL - מומלץ):התקנת WSL
wsl --install
בתוך WSL
cd /mnt/e/המצאות/NAU\ WORD/2048/core
./autogen.sh --enable-debug --disable-online-update
שלב 3: בנייה – רק מודול Writer (מהיר!)בנייה ראשונית מלאה (פעם אחת – עלולה לקחת 30-90 דקות)
make -j$(nproc)
לאחר שינויים בקבצי sw בלבד, בנה רק את המודול:
make sw -j$(nproc)
בנייה מהירה עוד יותר עם ninja:
make -j$(nproc) build-nocheck
שלב 4: בדיקת השינוייםהרצת LibreOffice עם השינויים
./instdir/program/swriter
פתח מסמך עם מספר הערות באותה שורה ובדוק שהן מופיעות זו לצד זו
שלב 5: הרצת טסטים
טסטים ספציפיים למודול Writer
make sw_uicheck
טסטים של annotations בלבד
cd sw && make CppunitTest_sw_uiwriter
נקודות תשומת לב
אל תשנה את לוגיקת ה-anchor – רק את חישוב ה-X
שמור על ה-POSTIT_SPACE_BETWEEN הקיים בין הערות
בדוק מקרי קצה: הערה אחת בשורה (צריכה להתנהג כרגיל), הערות בעמודות שונות
שים לב ל-RTL (עברית/ערבית) – המיקום האופקי מתהפך
הקובץ הקריטי הוא PostItMgr.cxx – 90% מהשינוי שם
חפש את הסמן mlPageBorder בקוד – כל מקום שמשתמש בו לציר X הוא מועמד לשינוי
קבצים ששונו
sw/inc/postithelper.hxx - שורה 106 (הוספת שדה mLayoutX)
sw/source/uibase/docvw/PostItMgr.cxx - שורות 990-1139 (שינוי לוגיקת פריסה)
סיכום
השינויים האלו מאפשרים להערות שמקושרות לאותה שורה בטקסט להופיע זו לצד זו במקום אחת מתחת לשנייה. השינוי הוא מינימלי וממוקד, ומשתמש במנגנון הקיים של LibreOffice לפריסת הערות, רק עם לוגיקה שונה לחישוב המיקום האופקי.תאריך: 20 במאי 2026
נכתב על ידי: Cascade (AI coding assistant)
בקשה מקורית: לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות אחת אחרי השנייה באותה שורה -
ביקשתי מה-AI ב-VS Code לסייע לי בבניית מהדורה של LibreOffice עם הערות ברצף. הגענו לשלב הסגירה, שבו נדרשת סביבת לינוקס שאינה זמינה לי כרגע.
ביקשתי ממנו לסכם את התהליך שביצע (או תכנן לבצע), ואני מצרף את הסיכום כאן בספוילר.
# מיקום אופקי של הערות ב-LibreOffice Writer - תיעוד שינויים
מי כתב את זה?
אני Cascade, AI coding assistant מבית Cognition. המשתמש ביקש ממני לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות (comments/annotations) אחת אחרי השנייה באותה שורה במקום שכל הערה תתחיל בשורה חדשה.המטרה
ב-LibreOffice Writer, כאשר מספר הערות מקושרות לאותה שורת טקסט, הן מופיעות אחת מתחת לשנייה בסרגל הצד. המטרה היא לאפשר שהערות שמקושרות לאותה שורה יופיעו זו לצד זו (אופקית) – ברצף, ולא כל אחת בשורה חדשה.ארכיטקטורת הקוד
מודול Writer = sw/
כל הקוד הרלוונטי נמצא תחת sw/source/uibase/docvw/קבצים מרכזיים
קובץ תפקיד
sw/source/uibase/docvw/PostItMgr.cxx הקובץ הראשי – ניהול ופריסת כל ההערות
sw/inc/postithelper.hxx מבנה SwLayoutInfo + SwAnnotationItem
לוגיקת הפריסה הנוכחית
LayoutPostIts() ← נקראת בכל רענון
└── LayoutByPage() ← מפרסת הערות לפי עמוד, מונעת חפיפה אנכית
└── SetPosSizePixelRect() ← קובע מיקום וגודל לכל הערה
כיצד נקבע המיקום כיום (לפני השינוי):// Y נקבע לפי מיקום ה-anchor בטקסט
tools::Long nY = mpEditWin->LogicToPixel(
Point(0, pItem->maLayoutInfo.mPosition.Bottom())).Y();// X נקבע תמיד לאותו ערך קבוע
tools::Long nX = mlPageBorder; // ← הבעיה! תמיד אותו X
השינויים שבוצעו
שינוי 1: הוספת שדה mLayoutX למבנה SwAnnotationItem
קובץ: sw/inc/postithelper.hxxשורה: 106
תוכן השינוי:
class SAL_DLLPUBLIC_RTTI SwAnnotationItem final
{
public:
VclPtrsw::annotation::SwAnnotationWin mpPostIt;
bool mbShow;
bool mbFocus;
bool mbPendingLayout;
SwPostItHelper::SwLayoutStatus mLayoutStatus;
SwLayoutInfo maLayoutInfo;
tools::Long mLayoutX = 0; // מיקום אופקי מחושב ← שדה חדש
הסבר: הוספתי שדה חדש mLayoutX למחלקה SwAnnotationItem כדי לשמור את המיקום האופקי המחושב של כל הערה.שינוי 2: שינוי לוגיקת הפריסה ב-PostItMgr.cxx
קובץ: sw/source/uibase/docvw/PostItMgr.cxxפונקציה: LayoutPostIts()
שורות: 990-1139
תוכן השינוי:
לפני השינוי (הקוד המקורי):
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( mlPageBorder , // ← תמיד אותו X Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
אחרי השינוי (הקוד החדש):
// שלב א: קיבוץ הערות לפי Y וחישוב מיקום אופקי
std::map<tools::Long, std::vector<SwAnnotationItem*>> aRowGroups;
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
tools::Long Y = mpEditWin->LogicToPixel(
Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y();
aRowGroups[Y].push_back(pItem.get());
}
}// שלב ב: לכל קבוצת Y – הקצה X שונה לכל הערה
tools::Long mlPageBorder = 0;
tools::Long mlPageEnd = 0;if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::LEFT )
{
mlPageBorder = mpEditWin->LogicToPixel(Point(pPage->mPageRect.Left(), 0)).X() - nSidebarWidth;
}
else if (pPage->eSidebarPosition == sw::sidebarwindows::SidebarPosition::RIGHT )
{
mlPageBorder = mpEditWin->LogicToPixel( Point(pPage->mPageRect.Right(), 0)).X() + GetSidebarBorderWidth(true);
}for (auto& [nY, aGroup] : aRowGroups)
{
tools::Long nX = mlPageBorder;
for (auto* pItem : aGroup)
{
pItem->mLayoutX = nX;
// חשב את הרוחב של ההערה
bool bCreated = false;
VclPtr<SwAnnotationWin> pPostIt = GetOrCreateAnnotationWindow(*pItem, bCreated);
if (bCreated)
{
aCreatedPostIts.insert(pPostIt);
}tools::Long nTextHeight; if (pPostIt->GetSizePixel().Width() == nSidebarWidth) nTextHeight = pPostIt->GetPostItTextHeight(); else nTextHeight = pPostIt->GuessTextHeightForWidth(nSidebarWidth); tools::Long postItPixelTextHeight = (comphelper::LibreOfficeKit::isActive() ? mpEditWin->LogicToPixel(Point(0, nTextHeight)).Y() : nTextHeight); tools::Long aPostItHeight = (postItPixelTextHeight < pPostIt->GetMinimumSizeWithoutMeta() ? pPostIt->GetMinimumSizeWithoutMeta() : postItPixelTextHeight) + pPostIt->GetMetaHeight(); nX += nSidebarWidth + GetSpaceBetween(); }}
// שלב ג: השתמש ב-mLayoutX בקריאה ל-SetPosSizePixelRect
for (auto const& pItem : pPage->mvSidebarItems)
{
if (pItem->mbShow)
{
// ... קוד ליצירת חלון הערה ...tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); // ... חישוב גובה ההערה ... pPostIt->SetPosSizePixelRect( pItem->mLayoutX , // ← מיקום X מחושב Y - GetInitialAnchorDistance(), nSidebarWidth, aPostItHeight, mlPageEnd ); }}
הסבר:שלב א: קיבוץ הערות לפי מיקום Y (שורה בטקסט)
שלב ב: לכל קבוצת Y, חישוב מיקום X שונה לכל הערה - הערות מקבלות מיקום X שונה בסדר
שלב ג: שימוש ב-mLayoutX בקריאה ל-SetPosSizePixelRect במקום mlPageBorder קבוע
איך זה עובד
הערות באותה שורה (אותו Y) יופיעו זו לצד זו
המרחק בין הערות נקבע על ידי nSidebarWidth + GetSpaceBetween()
הערות בשורות שונות יופיעו אחת מתחת לשנייה כרגיל
איך לבנות את הקוד
דרישות מקדימותודא שהכלים הבאים מותקנים:
git --version # נדרש git
cmake --version # נדרש cmake 3.15+
make --version # או ninja
gcc --version # gcc 7+ או clang 8+
שלב 1: הורדת הקוד (אם עדיין לא הורד)Clone מלא (גדול! ~4GB)
git clone https://gerrit.libreoffice.org/core libreoffice
cd libreofficeאו: clone רדוד יותר (מהיר יותר לפיתוח)
git clone --depth=1 https://gerrit.libreoffice.org/core libreoffice
cd libreofficeמשיכת submodules
git submodule update --init
שלב 2: הגדרת build
על Linux/macOS:
./autogen.sh
--enable-debug
--disable-online-update
--without-java
--without-help
--without-myspell-dicts
על Windows (MSYS2):
./autogen.sh --enable-debug --disable-online-update
על Windows (WSL - מומלץ):התקנת WSL
wsl --install
בתוך WSL
cd /mnt/e/המצאות/NAU\ WORD/2048/core
./autogen.sh --enable-debug --disable-online-update
שלב 3: בנייה – רק מודול Writer (מהיר!)בנייה ראשונית מלאה (פעם אחת – עלולה לקחת 30-90 דקות)
make -j$(nproc)
לאחר שינויים בקבצי sw בלבד, בנה רק את המודול:
make sw -j$(nproc)
בנייה מהירה עוד יותר עם ninja:
make -j$(nproc) build-nocheck
שלב 4: בדיקת השינוייםהרצת LibreOffice עם השינויים
./instdir/program/swriter
פתח מסמך עם מספר הערות באותה שורה ובדוק שהן מופיעות זו לצד זו
שלב 5: הרצת טסטים
טסטים ספציפיים למודול Writer
make sw_uicheck
טסטים של annotations בלבד
cd sw && make CppunitTest_sw_uiwriter
נקודות תשומת לב
אל תשנה את לוגיקת ה-anchor – רק את חישוב ה-X
שמור על ה-POSTIT_SPACE_BETWEEN הקיים בין הערות
בדוק מקרי קצה: הערה אחת בשורה (צריכה להתנהג כרגיל), הערות בעמודות שונות
שים לב ל-RTL (עברית/ערבית) – המיקום האופקי מתהפך
הקובץ הקריטי הוא PostItMgr.cxx – 90% מהשינוי שם
חפש את הסמן mlPageBorder בקוד – כל מקום שמשתמש בו לציר X הוא מועמד לשינוי
קבצים ששונו
sw/inc/postithelper.hxx - שורה 106 (הוספת שדה mLayoutX)
sw/source/uibase/docvw/PostItMgr.cxx - שורות 990-1139 (שינוי לוגיקת פריסה)
סיכום
השינויים האלו מאפשרים להערות שמקושרות לאותה שורה בטקסט להופיע זו לצד זו במקום אחת מתחת לשנייה. השינוי הוא מינימלי וממוקד, ומשתמש במנגנון הקיים של LibreOffice לפריסת הערות, רק עם לוגיקה שונה לחישוב המיקום האופקי.תאריך: 20 במאי 2026
נכתב על ידי: Cascade (AI coding assistant)
בקשה מקורית: לבדוק אם אפשר להוסיף אפשרות ב-LibreOffice Writer למקם הערות אחת אחרי השנייה באותה שורה -
-
@יאיר-דניאל משום מה חסום בחדרי מחשבים עבר מקום כי הקודמים כן נפתחו
עריכה : הורדתי מהחנות תוספים אז זה לא כל כך דחוף, לי עכ"פ
שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.
נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.
בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗
הרשמה התחברות
